ASP.NET Core için gRPC 'de kimlik doğrulaması ve yetkilendirme

, James bAyKiNg

Örnek kodu görüntüleme veya indirme (nasıl indirileceği)

GRPC hizmetini çağıran kullanıcıların kimliğini doğrulama

grpc, bir kullanıcıyı her çağrıyla ilişkilendirmek için ASP.NET Core kimlik doğrulamasıyla birlikte kullanılabilir.

aşağıda, Startup.Configure grpc ve ASP.NET Core kimlik doğrulaması kullanan bir örnek verilmiştir:

public void Configure(IApplicationBuilder app)
{
    app.UseRouting();
    
    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGrpcService<GreeterService>();
    });
}

Not

ASP.NET Core kimlik doğrulama ara yazılımını kaydetme sırası önemli. Her zaman UseAuthentication UseAuthorization ve sonra UseRouting ve sonra çağırın UseEndpoints .

Bir çağrı sırasında uygulamanızın kullandığı kimlik doğrulama mekanizması yapılandırılmalıdır. Kimlik doğrulama yapılandırması ' de eklenir Startup.ConfigureServices ve uygulamanızın kullandığı kimlik doğrulama mekanizmasına bağlı olarak farklı olacaktır. ASP.NET Core uygulamaları güvenli hale getirmeye yönelik örnekler için bkz. kimlik doğrulama örnekleri.

Kimlik doğrulaması kurulduktan sonra, Kullanıcı aracılığıyla bir gRPC hizmeti yöntemleriyle erişilebilir ServerCallContext .

public override Task<BuyTicketsResponse> BuyTickets(
    BuyTicketsRequest request, ServerCallContext context)
{
    var user = context.GetHttpContext().User;

    // ... access data from ClaimsPrincipal ...
}

Taşıyıcı belirteç kimlik doğrulaması

İstemci, kimlik doğrulaması için bir erişim belirteci sağlayabilir. Sunucu belirteci doğrular ve kullanıcıyı tanımlamak için kullanır.

Sunucusunda, taşıyıcı belirteç kimlik doğrulaması JWT taşıyıcı ara yazılımıkullanılarak yapılandırılır.

.NET gRPC istemcisinde, belirteç, koleksiyon kullanılarak çağrılarla gönderilebilir Metadata . MetadataKoleksiyondaki girişler, http üstbilgileri olarak bir gRPC çağrısıyla gönderilir:

public bool DoAuthenticatedCall(
    Ticketer.TicketerClient client, string token)
{
    var headers = new Metadata();
    headers.Add("Authorization", $"Bearer {token}");

    var request = new BuyTicketsRequest { Count = 1 };
    var response = await client.BuyTicketsAsync(request, headers);

    return response.Success;
}

ChannelCredentialsKanalı üzerinde yapılandırmak, belirteci gRPC çağrılarıyla hizmete göndermenin alternatif bir yoludur. ChannelCredentials CallCredentials , Otomatik olarak ayarlanması için bir yol sağlayan, içerebilir Metadata .

CallCredentials Her bir gRPC çağrısı yapıldığında çalıştırılır ve bu, belirteci kendiniz geçirmek için birden çok yere kod yazma ihtiyacını önler. CallCredentialsYalnızca KANALıN TLS ile güvenliği sağlanmasıyla uygulandığını unutmayın. CallCredentials güvenli olmayan TLS olmayan kanallarda uygulanmaz.

Aşağıdaki örnekteki kimlik bilgileri, kanalı her gRPC çağrısıyla birlikte gönderecek şekilde yapılandırır:

private static GrpcChannel CreateAuthenticatedChannel(string address)
{
    var credentials = CallCredentials.FromInterceptor((context, metadata) =>
    {
        if (!string.IsNullOrEmpty(_token))
        {
            metadata.Add("Authorization", $"Bearer {_token}");
        }
        return Task.CompletedTask;
    });

    // SslCredentials is used here because this channel is using TLS.
    // CallCredentials can't be used with ChannelCredentials.Insecure on non-TLS channels.
    var channel = GrpcChannel.ForAddress(address, new GrpcChannelOptions
    {
        Credentials = ChannelCredentials.Create(new SslCredentials(), credentials)
    });
    return channel;
}

GRPC istemci fabrikası ile taşıyıcı belirteci

gRPC istemci fabrikası, kullanarak bir taşıyıcı belirteci gönderen istemciler oluşturabilir ChannelCredentials . Bir istemciyi yapılandırırken, CallCredentials istemcisini yöntemiyle kullanması gerekir ConfigureChannel .

services
    .AddGrpcClient<Greeter.GreeterClient>(o =>
    {
        o.Address = new Uri("https://localhost:5001");
    })
    .ConfigureChannel(o =>
    {
        var credentials = CallCredentials.FromInterceptor((context, metadata) =>
        {
            if (!string.IsNullOrEmpty(_token))
            {
                metadata.Add("Authorization", $"Bearer {_token}");
            }
            return Task.CompletedTask;
        });

        o.Credentials = ChannelCredentials.Create(new SslCredentials(), credentials);
    });

İstemci sertifikası kimlik doğrulaması

İstemci alternatif olarak kimlik doğrulaması için bir istemci sertifikası sağlayabilir. Sertifika kimlik doğrulaması TLS düzeyinde gerçekleşir ve bu süre ASP.NET Core. istek ASP.NET Core girdiğinde, istemci sertifikası kimlik doğrulama paketi , sertifikayı bir ile çözmenize olanak tanır ClaimsPrincipal .

Not

Sunucuyu istemci sertifikalarını kabul edecek şekilde yapılandırın. , IIS ve Azure 'da istemci sertifikalarını kabul etme hakkında bilgi için Kestrel bkz ASP.NET Core sertifika kimlik doğrulamasını yapılandırma ..

.NET gRPC istemcisinde, HttpClientHandler daha sonra gRPC istemcisini oluşturmak için kullanılan istemci sertifikası eklenir:

public Ticketer.TicketerClient CreateClientWithCert(
    string baseAddress,
    X509Certificate2 certificate)
{
    // Add client cert to the handler
    var handler = new HttpClientHandler();
    handler.ClientCertificates.Add(certificate);

    // Create the gRPC channel
    var channel = GrpcChannel.ForAddress(baseAddress, new GrpcChannelOptions
    {
        HttpHandler = handler
    });

    return new Ticketer.TicketerClient(channel);
}

Diğer kimlik doğrulama mekanizmaları

desteklenen birçok ASP.NET Core kimlik doğrulama mekanizması grpc ile çalışır:

  • Azure Active Directory
  • İstemci sertifikası
  • IdentitySunucu
  • JWT belirteci
  • OAuth 2.0
  • OpenID Connect
  • WS-Federation

sunucuda kimlik doğrulamasını yapılandırma hakkında daha fazla bilgi için, ASP.NET Core kimlik doğrulaması' na bakın.

GRPC istemcisini kimlik doğrulaması kullanacak şekilde yapılandırmak, kullanmakta olduğunuz kimlik doğrulama mekanizmasına bağlı olarak değişir. Önceki taşıyıcı belirteci ve istemci sertifikası örnekleri, GRPC istemcisinin, gRPC çağrılarına yönelik kimlik doğrulama meta verilerini gönderecek şekilde yapılandırılabilmesinin birkaç yolunu gösterir:

  • Türü kesin belirlenmiş gRPC istemcileri HttpClient dahili olarak kullanılır. Kimlik doğrulaması, HttpClientHandlerüzerinde veya öğesine özel HttpMessageHandler örnekleri eklenerek yapılandırılabilir HttpClient .
  • Her gRPC çağrısının isteğe bağlı bir CallOptions bağımsız değişkeni vardır. Özel üstbilgiler, seçeneğin üstbilgiler koleksiyonu kullanılarak gönderilebilir.

Not

Windows Kimlik doğrulaması (NTLM/Kerberos/Negotiate) gRPC ile kullanılamaz. grpc için http/2 ve http/2 Windows kimlik doğrulamasını desteklemez.

Kullanıcılara hizmetlere ve hizmet yöntemlerine erişim yetkisi verme

Varsayılan olarak, bir hizmette tüm yöntemler kimliği doğrulanmamış kullanıcılar tarafından çağrılabilir. Kimlik doğrulaması gerektirmek için, [Authorize] özelliği hizmetine uygulayın:

[Authorize]
public class TicketerService : Ticketer.TicketerBase
{
}

[Authorize]Yalnızca belirli Yetkilendirme ilkeleriyleeşleşen kullanıcılara erişimi kısıtlamak için özniteliğinin Oluşturucu bağımsız değişkenlerini ve özelliklerini kullanabilirsiniz. Örneğin, adlı bir özel yetkilendirme ilkeniz varsa MyAuthorizationPolicy , aşağıdaki kodu kullanarak yalnızca bu ilkeyle eşleşen kullanıcıların hizmete erişebildiğinden emin olun:

[Authorize("MyAuthorizationPolicy")]
public class TicketerService : Ticketer.TicketerBase
{
}

Bağımsız hizmet yöntemlerinin [Authorize] özniteliği de uygulanabilir. Geçerli Kullanıcı hem yönteme hem de sınıfa uygulanan ilkelerle eşleşmezse, çağırana bir hata döndürülür:

[Authorize]
public class TicketerService : Ticketer.TicketerBase
{
    public override Task<AvailableTicketsResponse> GetAvailableTickets(
        Empty request, ServerCallContext context)
    {
        // ... buy tickets for the current user ...
    }

    [Authorize("Administrators")]
    public override Task<BuyTicketsResponse> RefundTickets(
        BuyTicketsRequest request, ServerCallContext context)
    {
        // ... refund tickets (something only Administrators can do) ..
    }
}

Ek kaynaklar