Ověřování a autorizace v gRPC pro ASP.NET Core
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Upozorňující
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v zásadách podpory .NET a .NET Core. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Autor: James Newton-King
Zobrazení nebo stažení ukázkového kódu (postup stažení)
Ověřování uživatelů, kteří volají službu gRPC
GRPC lze použít s ověřováním ASP.NET Core k přidružení uživatele k jednotlivým voláním.
Následuje příklad Program.cs
použití gRPC a ověřování ASP.NET Core:
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapGrpcService<GreeterService>();
Poznámka:
Pořadí, ve kterém zaregistrujete middleware ověřování ASP.NET Core, záleží. Vždy zavolat UseAuthentication
a za a před UseRouting
UseEndpoints
.UseAuthorization
Ověřovací mechanismus, který vaše aplikace používá během volání, je potřeba nakonfigurovat. Konfigurace ověřování se přidá Program.cs
a bude se lišit v závislosti na mechanismu ověřování, který vaše aplikace používá.
Po nastavení ověřování je uživatel přístupný v metodách služby gRPC prostřednictvím ServerCallContext
metody .
public override Task<BuyTicketsResponse> BuyTickets(
BuyTicketsRequest request, ServerCallContext context)
{
var user = context.GetHttpContext().User;
// ... access data from ClaimsPrincipal ...
}
Ověřování nosný token
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 ověřování nosných tokenů konfiguruje pomocí middlewaru JWT Bearer.
V klientovi .NET gRPC lze token odeslat s voláními pomocí Metadata
kolekce. Položky v kolekci Metadata
se odesílají s voláním gRPC jako hlavičky 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;
}
Nastavení nosné tokeny pomocí CallCredentials
Konfigurace ChannelCredentials
v kanálu představuje alternativní způsob odeslání tokenu do služby pomocí volání gRPC. A ChannelCredentials
může zahrnovat CallCredentials
, které poskytují způsob, jak automaticky nastavit Metadata
.
Výhody použití CallCredentials
:
- Ověřování je centrálně nakonfigurované v kanálu. Token nemusí být ručně poskytnut volání gRPC.
CallCredentials.FromInterceptor
Zpětné volání je asynchronní. V případě potřeby může volání přihlašovacích údajů načíst token přihlašovacích údajů z externího systému. Asynchronní metody uvnitř zpětného volání by měly používat onCancellationToken
AuthInterceptorContext
.
Poznámka:
CallCredentials
jsou použity pouze v případě, že je kanál zabezpečený protokolem TLS. Odesílání hlaviček ověřování přes nezabezpečené připojení má vliv na zabezpečení a nemělo by se provádět v produkčních prostředích. Aplikace může nakonfigurovat kanál tak, aby toto chování ignoroval a vždy ho používal CallCredentials
nastavením UnsafeUseInsecureChannelCallCredentials
kanálu.
Přihlašovací údaje v následujícím příkladu konfigurují kanál tak, aby odesílal token s každým voláním gRPC:
private static GrpcChannel CreateAuthenticatedChannel(ITokenProvder tokenProvider)
{
var credentials = CallCredentials.FromInterceptor(async (context, metadata) =>
{
var token = await tokenProvider.GetTokenAsync(context.CancellationToken);
metadata.Add("Authorization", $"Bearer {token}");
});
var channel = GrpcChannel.ForAddress(address, new GrpcChannelOptions
{
Credentials = ChannelCredentials.Create(new SslCredentials(), credentials)
});
return channel;
}
Nosný token s klientskou továrnou gRPC
Klientská továrna gRPC může vytvářet klienty, kteří odesílají nosný token pomocí AddCallCredentials
. Tato metoda je k dispozici v Grpc.Net.ClientFactory verze 2.46.0 nebo novější.
Delegát předaný je AddCallCredentials
spuštěn pro každé volání gRPC:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddCallCredentials((context, metadata) =>
{
if (!string.IsNullOrEmpty(_token))
{
metadata.Add("Authorization", $"Bearer {_token}");
}
return Task.CompletedTask;
});
Injektáž závislostí (DI) lze kombinovat s AddCallCredentials
. Přetížení se předá IServiceProvider
delegátu, který lze použít k získání služby vytvořené z DI pomocí vymezených a přechodných služeb.
Představte si aplikaci, která má:
- Uživatelem definovaný
ITokenProvider
pro získání nosné tokeny.ITokenProvider
aplikace is registered in DI with a scoped lifetime. - Klientská továrna gRPC je nakonfigurovaná tak, aby vytvářela klienty vložené do služeb gRPC a řadičů webového rozhraní API.
- Volání gRPC by se měla použít
ITokenProvider
k získání nosný token.
public interface ITokenProvider
{
Task<string> GetTokenAsync(CancellationToken cancellationToken);
}
public class AppTokenProvider : ITokenProvider
{
private string _token;
public async Task<string> GetTokenAsync(CancellationToken cancellationToken)
{
if (_token == null)
{
// App code to resolve the token here.
}
return _token;
}
}
builder.Services.AddScoped<ITokenProvider, AppTokenProvider>();
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddCallCredentials(async (context, metadata, serviceProvider) =>
{
var provider = serviceProvider.GetRequiredService<ITokenProvider>();
var token = await provider.GetTokenAsync(context.CancellationToken);
metadata.Add("Authorization", $"Bearer {token}");
}));
Předchozí kód:
ITokenProvider
Definuje aAppTokenProvider
. Tyto typy zpracovávají překlad ověřovacího tokenu pro volání gRPC.- Zaregistruje
AppTokenProvider
typ v oboru životnosti pomocí DI.AppTokenProvider
uloží token do mezipaměti, aby se k výpočtu vyžadovalo pouze první volání v oboru. - Zaregistruje typ v
GreeterClient
klientské továrně. - Konfiguruje
AddCallCredentials
pro tohoto klienta. Delegát se spustí při každém volání a přidá token vrácenýITokenProvider
do metadat.
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 někdy dostane k ASP.NET Core. Když požadavek zadá ASP.NET Core, balíček ověřování klientských certifikátů umožňuje přeložit certifikát na ClaimsPrincipal
.
Poznámka:
Nakonfigurujte server tak, aby přijímal klientské certifikáty. Informace o přijetí klientských certifikátů ve Kestrelslužbě , IIS a Azure najdete v tématu Konfigurace ověřování certifikátů v ASP.NET Core.
V klientovi .NET gRPC se do klienta přidá klientský certifikát, který HttpClientHandler
se pak použije k 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í
Mnoho ASP.NET core podporovaných ověřovacích mechanismů funguje s gRPC:
- Microsoft Entra ID
- 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 Základní 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í nosný token a příklady klientských certifikátů ukazují několik způsobů, jak lze klienta gRPC nakonfigurovat tak, aby odesílala metadata ověřování pomocí volání gRPC:
- Klienti gRPC silného typu používají
HttpClient
interně. Ověřování lze nakonfigurovat na HttpClientHandlernebo přidáním vlastních HttpMessageHandler instancí 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:
Ověřování systému Windows (NTLM/ Kerberos/Negotiate) se nedá použít s gRPC. gRPC vyžaduje HTTP/2 a HTTP/2 nepodporuje ověřování systému Windows.
Autorizace uživatelů pro přístup ke službám a metodám služeb
Ve výchozím nastavení můžou všechny metody ve službě volat neověřené uživatele. Pokud chcete vyžadovat ověření, použijte [Authorize]
atribut pro službu:
[Authorize]
public class TicketerService : Ticketer.TicketerBase
{
}
Pomocí argumentů a vlastností konstruktoru atributu [Authorize]
můžete omezit přístup pouze na uživatele, kteří odpovídají konkrétním zásadám autorizace. Pokud máte například volanou MyAuthorizationPolicy
vlastní autorizační zásadu, ujistěte se, že k této službě mají přístup pouze uživatelé odpovídající této zásadě, a to pomocí následujícího kódu:
[Authorize("MyAuthorizationPolicy")]
public class TicketerService : Ticketer.TicketerBase
{
}
Jednotlivé metody služby mohou mít [Authorize]
také použitý atribut. Pokud aktuální uživatel neodpovídá zásadám použitým pro metodu i třídu, vrátí se volajícímu 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ší materiály
Zobrazení nebo stažení ukázkového kódu (postup stažení)
Ověřování uživatelů, kteří volají službu gRPC
GRPC lze použít s ověřováním ASP.NET Core k přidružení uživatele k jednotlivým voláním.
Následuje příklad Startup.Configure
použití gRPC a ověřování ASP.NET Core:
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<GreeterService>();
});
}
Poznámka:
Pořadí, ve kterém zaregistrujete middleware ověřování ASP.NET Core, záleží. Vždy zavolat UseAuthentication
a za a před UseRouting
UseEndpoints
.UseAuthorization
Ověřovací mechanismus, který vaše aplikace používá během volání, je potřeba nakonfigurovat. Konfigurace ověřování se přidá Startup.ConfigureServices
a bude se lišit v závislosti na mechanismu ověřování, který vaše aplikace používá.
Po nastavení ověřování je uživatel přístupný v metodách služby gRPC prostřednictvím ServerCallContext
metody .
public override Task<BuyTicketsResponse> BuyTickets(
BuyTicketsRequest request, ServerCallContext context)
{
var user = context.GetHttpContext().User;
// ... access data from ClaimsPrincipal ...
}
Ověřování nosný token
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 ověřování nosných tokenů konfiguruje pomocí middlewaru JWT Bearer.
V klientovi .NET gRPC lze token odeslat s voláními pomocí Metadata
kolekce. Položky v kolekci Metadata
se odesílají s voláním gRPC jako hlavičky 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;
}
Nastavení nosné tokeny pomocí CallCredentials
Konfigurace ChannelCredentials
v kanálu představuje alternativní způsob odeslání tokenu do služby pomocí volání gRPC. A ChannelCredentials
může zahrnovat CallCredentials
, které poskytují způsob, jak automaticky nastavit Metadata
.
Výhody použití CallCredentials
:
- Ověřování je centrálně nakonfigurované v kanálu. Token nemusí být ručně poskytnut volání gRPC.
CallCredentials.FromInterceptor
Zpětné volání je asynchronní. V případě potřeby může volání přihlašovacích údajů načíst token přihlašovacích údajů z externího systému. Asynchronní metody uvnitř zpětného volání by měly používat onCancellationToken
AuthInterceptorContext
.
Poznámka:
CallCredentials
jsou použity pouze v případě, že je kanál zabezpečený protokolem TLS. Odesílání hlaviček ověřování přes nezabezpečené připojení má vliv na zabezpečení a nemělo by se provádět v produkčních prostředích. Aplikace může nakonfigurovat kanál tak, aby toto chování ignoroval a vždy ho používal CallCredentials
nastavením UnsafeUseInsecureChannelCallCredentials
kanálu.
Přihlašovací údaje v následujícím příkladu konfigurují kanál tak, aby odesílal token s každým voláním gRPC:
private static GrpcChannel CreateAuthenticatedChannel(ITokenProvder tokenProvider)
{
var credentials = CallCredentials.FromInterceptor(async (context, metadata) =>
{
var token = await tokenProvider.GetTokenAsync(context.CancellationToken);
metadata.Add("Authorization", $"Bearer {token}");
});
var channel = GrpcChannel.ForAddress(address, new GrpcChannelOptions
{
Credentials = ChannelCredentials.Create(new SslCredentials(), credentials)
});
return channel;
}
Nosný token s klientskou továrnou gRPC
Klientská továrna gRPC může vytvářet klienty, kteří odesílají nosný token pomocí AddCallCredentials
. Tato metoda je k dispozici v Grpc.Net.ClientFactory verze 2.46.0 nebo novější.
Delegát předaný je AddCallCredentials
spuštěn pro každé volání gRPC:
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddCallCredentials((context, metadata) =>
{
if (!string.IsNullOrEmpty(_token))
{
metadata.Add("Authorization", $"Bearer {_token}");
}
return Task.CompletedTask;
});
Injektáž závislostí (DI) lze kombinovat s AddCallCredentials
. Přetížení se předá IServiceProvider
delegátu, který lze použít k získání služby vytvořené z DI pomocí vymezených a přechodných služeb.
Představte si aplikaci, která má:
- Uživatelem definovaný
ITokenProvider
pro získání nosné tokeny.ITokenProvider
aplikace is registered in DI with a scoped lifetime. - Klientská továrna gRPC je nakonfigurovaná tak, aby vytvářela klienty vložené do služeb gRPC a řadičů webového rozhraní API.
- Volání gRPC by se měla použít
ITokenProvider
k získání nosný token.
public interface ITokenProvider
{
Task<string> GetTokenAsync(CancellationToken cancellationToken);
}
public class AppTokenProvider : ITokenProvider
{
private string _token;
public async Task<string> GetTokenAsync(CancellationToken cancellationToken)
{
if (_token == null)
{
// App code to resolve the token here.
}
return _token;
}
}
services.AddScoped<ITokenProvider, AppTokenProvider>();
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddCallCredentials(async (context, metadata, serviceProvider) =>
{
var provider = serviceProvider.GetRequiredService<ITokenProvider>();
var token = await provider.GetTokenAsync(context.CancellationToken);
metadata.Add("Authorization", $"Bearer {token}");
}));
Předchozí kód:
ITokenProvider
Definuje aAppTokenProvider
. Tyto typy zpracovávají překlad ověřovacího tokenu pro volání gRPC.- Zaregistruje
AppTokenProvider
typ v oboru životnosti pomocí DI.AppTokenProvider
uloží token do mezipaměti, aby se k výpočtu vyžadovalo pouze první volání v oboru. - Zaregistruje typ v
GreeterClient
klientské továrně. - Konfiguruje
AddCallCredentials
pro tohoto klienta. Delegát se spustí při každém volání a přidá token vrácenýITokenProvider
do metadat.
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 někdy dostane k ASP.NET Core. Když požadavek zadá ASP.NET Core, balíček ověřování klientských certifikátů umožňuje přeložit certifikát na ClaimsPrincipal
.
Poznámka:
Nakonfigurujte server tak, aby přijímal klientské certifikáty. Informace o přijetí klientských certifikátů ve Kestrelslužbě , IIS a Azure najdete v tématu Konfigurace ověřování certifikátů v ASP.NET Core.
V klientovi .NET gRPC se do klienta přidá klientský certifikát, který HttpClientHandler
se pak použije k 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í
Mnoho ASP.NET core podporovaných ověřovacích mechanismů funguje s gRPC:
- Microsoft Entra ID
- 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 Základní 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í nosný token a příklady klientských certifikátů ukazují několik způsobů, jak lze klienta gRPC nakonfigurovat tak, aby odesílala metadata ověřování pomocí volání gRPC:
- Klienti gRPC silného typu používají
HttpClient
interně. Ověřování lze nakonfigurovat na HttpClientHandlernebo přidáním vlastních HttpMessageHandler instancí 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:
Ověřování systému Windows (NTLM/ Kerberos/Negotiate) se nedá použít s gRPC. gRPC vyžaduje HTTP/2 a HTTP/2 nepodporuje ověřování systému Windows.
Autorizace uživatelů pro přístup ke službám a metodám služeb
Ve výchozím nastavení můžou všechny metody ve službě volat neověřené uživatele. Pokud chcete vyžadovat ověření, použijte [Authorize]
atribut pro službu:
[Authorize]
public class TicketerService : Ticketer.TicketerBase
{
}
Pomocí argumentů a vlastností konstruktoru atributu [Authorize]
můžete omezit přístup pouze na uživatele, kteří odpovídají konkrétním zásadám autorizace. Pokud máte například volanou MyAuthorizationPolicy
vlastní autorizační zásadu, ujistěte se, že k této službě mají přístup pouze uživatelé odpovídající této zásadě, a to pomocí následujícího kódu:
[Authorize("MyAuthorizationPolicy")]
public class TicketerService : Ticketer.TicketerBase
{
}
Jednotlivé metody služby mohou mít [Authorize]
také použitý atribut. Pokud aktuální uživatel neodpovídá zásadám použitým pro metodu i třídu, vrátí se volajícímu 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) ..
}
}
Metody rozšíření autorizace
Autorizaton lze také řídit pomocí standardních metod rozšíření autorizace ASP.NET Core, jako AllowAnonymous
jsou a RequireAuthorization
.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGrpc();
var app = builder.Build();
app.MapGrpcService<TicketerService>().RequireAuthorization("Administrators");
app.Run();