Ověřování a autorizace v gRPC pro ASP.NET Core
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) ..
}
}
Další materiály
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro