Ověřování a autorizace v gRPC pro ASP.NET Core

James Newton-King

Zobrazení nebo stažení ukázkového kódu (stažení)

Ověření uživatelů volajících službu gRPC

gRPC lze použít s ověřováním ASP.NET Core k přidružení uživatele ke každému volání.

Následuje příklad, který používá Startup.Configure gRPC a ASP.NET Core ověřování:

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

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

Poznámka

Na pořadí, ve kterém zaregistrujete ASP.NET Core middleware ověřování. Vždy UseAuthentication volejte UseAuthorization a po a před UseRouting UseEndpoints .

Je potřeba nakonfigurovat mechanismus ověřování, který vaše aplikace používá během volání. Konfigurace ověřování se přidá do a bude se lišit v závislosti na mechanismu Startup.ConfigureServices ověřování, který vaše aplikace používá. Příklady zabezpečení aplikací pro ASP.NET Core najdete v tématu Ukázky ověřování.

Po nastavení ověřování je uživatel přístupný prostřednictvím metod služby gRPC prostřednictvím ServerCallContext .

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

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

Ověřování pomocí tokenu bearer

Klient může poskytnout přístupový token pro ověřování. Server token ověří a použije ho k identifikaci uživatele.

Na serveru se konfiguruje ověřování pomocí bearerového middlewaru JWT.

V klientovi .NET gRPC je možné token odeslat s voláními pomocí Metadata kolekce . Položky v Metadata kolekci se odesílaly s voláním gRPC jako hlavičkami HTTP:

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;
}

Konfigurace na kanálu je alternativní způsob, jak odeslat token do služby pomocí ChannelCredentials volání gRPC. Může ChannelCredentials obsahovat , který poskytuje CallCredentials způsob, jak automaticky nastavit Metadata .

CallCredentials se spustí pokaždé, když je provedeno volání gRPC, což zabraňuje tomu, že je potřeba psát kód na více místech, abyste token předaly sami. CallCredentialsUpozorňujeme, že se použijí jenom v případě, že je kanál zabezpečený protokolem TLS. CallCredentials nejsou použity u nezabezpečených kanálů mimo TLS.

Přihlašovací údaje v následujícím příkladu nakonfigurují kanál tak, aby při každém volání gRPC odesílal token:

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;
}

Bearer token s klientskou továrnou gRPC

Klientská továrna gRPC může vytvářet klienty, kteří odesílat bearer token pomocí ChannelCredentials . Při konfiguraci klienta přiřaďte CallCredentials klientovi ConfigureChannel metodu .

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);
    });

Ověřování klientských certifikátů

Klient může případně poskytnout klientský certifikát pro ověřování. Ověřování certifikátů probíhá na úrovni protokolu TLS, dlouho předtím, než se ASP.NET Core. Po zadání požadavku ASP.NET Core ověřovací balíček klientského certifikátu umožňuje přeložit certifikát na ClaimsPrincipal .

Poznámka

Nakonfigurujte server tak, aby přijímal klientské certifikáty. Informace o přijímání klientských certifikátů v , IIS a Kestrel Azure najdete v tématu Konfigurace ověřování certifikátů v ASP.NET Core .

V klientovi .NET gRPC se klientský certifikát přidá do , který se pak použije k HttpClientHandler vytvoření klienta gRPC:

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);
}

Další mechanismy ověřování

S ASP.NET Core gRPC pracuje řada podporovaných mechanismů ověřování:

  • Azure Active Directory
  • Klientský certifikát
  • IdentityServer
  • JWT Token
  • OAuth 2.0
  • OpenID Connect
  • WS-Federation

Další informace o konfiguraci ověřování na serveru najdete v tématu ASP.NET Core ověřování.

Konfigurace klienta gRPC pro použití ověřování bude záviset na mechanismu ověřování, který používáte. Předchozí příklady bearer tokenu a klientského certifikátu ukazují několik způsobů, jak lze klienta gRPC nakonfigurovat tak, aby odesílal ověřovací metadata pomocí volání gRPC:

  • Klienti gRPC silného typu HttpClient používají interně. Ověřování je možné nakonfigurovat na HttpClientHandlernebo přidáním vlastních instancí HttpMessageHandler do HttpClient .
  • Každé volání gRPC má volitelný CallOptions argument. Vlastní hlavičky je možné odeslat pomocí kolekce hlaviček možnosti .

Poznámka

Windows S gRPC není možné použít ověřování (NTLM/Kerberos/Negotiate). gRPC vyžaduje HTTP/2 a HTTP/2 nepodporuje Windows ověřování.

Autorizace uživatelů pro přístup ke službám a metodám služeb

Ve výchozím nastavení mohou neověření uživatelé volat všechny metody ve službě. Pokud chcete vyžadovat ověření, [Authorize] použijte na službu atribut :

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

Pomocí argumentů konstruktoru a vlastností atributu můžete omezit přístup pouze na uživatele odpovídající [Authorize] konkrétním zásadám autorizace. Pokud máte například vlastní zásady autorizace s názvem , pomocí následujícího kódu zajistěte, aby ke službě měli přístup jenom uživatelé odpovídající této MyAuthorizationPolicy zásadám:

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

Jednotlivé metody služby mohou mít [Authorize] atribut použitý také. Pokud aktuální uživatel neodpovídá zásadám použitým pro metodu i třídu , volajícímu se vrátí chyba:

[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) ..
    }
}

Další zdroje informací