英文:
How could do the authentication and authorization in a gRPC service in a ASP Core application?
问题
我有一个托管在ASP Core NET 7应用程序中的gRPC服务。
我正在研究如何在ASP Core层级使用JWT来对客户进行身份验证和授权,但我不知道如何在gRPC层级执行它。
我的应用程序结构如下:Asp Core --> gRPC --> 应用程序层
Asp Core只是托管gRPC服务,但似乎也处理身份验证。但在gRPC服务中,我需要对用户进行身份验证,以便获取客户端的ID以获取某些数据。
例如,我在gRPC服务中有以下方法:
class MyBankService
{
BankAccount GetBankAccountOfClient(long clientId)
{
Client myClient = _clientsRepository.GetClient(username, password);
return myApplicationSerivice.GetBankAccountOfClient(myClient.Id);
}
}
通过这个示例,我试图说明我需要从数据库中获取与客户端发送的凭据对应的客户端的ID,以便获取客户端的银行帐户。
我不知道是否应该在服务器上有一个登录方法来获取ID并使用JWT令牌的字典与用户关联,类似于以下示例:
class MyBankService
{
Dictionary<object, long> _clientIds = new Dictionary<object, long>();
void Login(string paramUserName, string paramPassword)
{
Client myClient = _clientRepository.GetClient(paramUserName, paramPassword);
string myHashedPassword = HashPassword(paramPassword);
if (myHashedPassword == myClient.HashedPassword)
{
_dictionary.Add(token, myClient.Id); //从哪里获取令牌?
}
else
{
throw new Exception("User not valid.");
}
}
BankAccount GetBankAccountOfClient(object token)
{
//从哪里获取令牌?
if (!_dictionary.ContainsKey(token)) throw exception();
//如果有效,因为它可能已过期或其他原因。
if (!CheckIsTokenIsValid(token)) throw exception();
return applicationService.GetBankAccountOfClient(_dictionary[token].Id);
}
}
但如果这是一种正确的方式,从哪里获取令牌?令牌过期时,我必须从字典中删除它,所以我需要维护字典,这是更多的工作。如果有许多用户,是否有一个大字典存储所有令牌和ID的好主意?
我确信应该有另一种更好的方式来处理所有这些,但我不知道其他选择。也许使用拦截器?
总之,我想知道如何处理授权的方式,以及如何获取客户端的所需数据以过滤数据并确保不会发送客户端应该看到的数据。
英文:
I have a gRPC service that is hosted in an ASP Core NET 7 application.
I am reading how to use JWT to authenticate and authorize a client at ASP Core level, but I don't know how to do it in the gRPC level.
My application has this strcuture: Asp Core --> gRPC --> application layer
Asp Core just host the gRPC service, but it seems it handle the authentication too. But in the gRPC service I need to authenticate the user to can get the ID of the client to can get some data.
For example, I have this method in the gRPC service:
class MyBankService
{
BankAccount GetBankAccountOfClient(long clientId)
{
Client myClient = _clientsRepository.GetClient(username, password);
return myApplicationSerivice.GetBankAccountOfClient(myClient.Id);
}
}
With this example, I try to show how I need to get the Id of the client from the database that correspond to the credentials sending from the client to can get the bank account of the client.
I don't know if I should to have a login method in my server to get the id and to have a dictionary with the JWT token and relate it with the user, something like that:
class MyBankService
{
Dictionary<object, long> _clientIds = new Dictionary<object, long>();
void Login(string paramUserName, string paramPassword)
{
Client myClient = _clientRepository.GetClient(paramUserName, paramPassword);
string myHashedPassword = HasPassword(paramPassword);
if(myHashedPassword == myClient.HashedPassword)
{
_dictionary.Add(token, myClient.Id); //where to get the token?
}
else
{
throw new Exception("User not valid.");
}
}
BankAccount GetBankAccountOfClient(object token)
{
//from where to get the token???
if(_dictionary.ContainsKey(token) == false) throw exception();
//if valid because it can be expired or another reason.
if(CheckIsTokenIsValid(token) == false) throw exception();
return applicationService.GetBankAccountOfClient(_dictionary[token].Id);
}
}
But if this is a correct way, from where to get the token? And when the token is expired, I would have to delete from dictionary, so I should to do a maintenance of the dictionary, so it is more work. And if I have many users, is it a good idea to have a big dictionary with all the tokens and Ids?
I am sure that there should be another better way to handle all this, but I don't know alternatives. Perhaps with interceptors?
So in summary, I would like to know the way to handle the authorization and how to get the needed data of the client to filter data and ensure I will not send data that the client should see.
Thanks.
答案1
得分: 1
<h1>令牌处理(JWT)</h1>
JWT令牌完全适应您的需求:
- 您决定存储哪些字段
- 发行的令牌中包含的所有私有数据(仅在私有声明中)都是安全的
- 使用JWT处理请求时,您可以解密令牌中的数据
- 无需服务器存储
- JWT中的数据可以在服务器之间共享(因此不要在公共声明中定义敏感信息)
- 简便的.NET设置
如何设置:
- 添加NuGet
```
PM> Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
```
- 配置JWT设置(例如在appsettings.json中)
```
"Jwt": {
"Issuer": "https://joydipkanjilal.com/",
"Audience": "https://joydipkanjilal.com/",
"Key": "This is a sample secret key - please don't use in production environment."
}
```
- 在Program.cs(或Startup.cs)文件中配置身份验证
```
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
});
```
- 配置身份验证服务
```
builder.Services.AddAuthorization();
...
app.UseAuthentication();
app.UseAuthorization();
```
设置完成,您已准备好进行身份验证实现!
我推荐使用[这篇文章][1]来开始在.NET中使用JWT身份验证。有关JWT的更多信息,请参见[链接][2]。
<h1>gRPC身份验证</h1>
根据[文档][3],您可以通过对gRPC服务进行配置来配置身份验证/授权。
> 拦截器是gRPC的概念,允许应用程序与传入或传出的gRPC调用交互。它们提供了一种丰富请求处理管道的方式。
换句话说,您需要:
- 创建新的AuthInterceptor
- 用身份验证逻辑覆盖`AsyncUnaryCall`方法
还可以查看stackoverflow上的类似[问题][4],其中介绍了在grpcClient上设置令牌的方法。
[1]: https://www.infoworld.com/article/3669188/how-to-implement-jwt-authentication-in-aspnet-core-6.html
[2]: https://jwt.io/introduction
[3]: https://learn.microsoft.com/en-us/aspnet/core/grpc/interceptors?view=aspnetcore-7.0
[4]: https://stackoverflow.com/questions/68442239/c-sharp-grpc-client-interceptor-set-authorization-header
英文:
<h1>Token handle (JWT)</h1>
JWT token perfectly fit to your needs:
- You decide which fields to store in
- All your private data contained in issued token secured (in private claims only)
- On request with JWT handle, you can decrypt data in token
- No server storage required
- Data in JWT can be shared between servers (so dont define sensetive information in public claims)
- Easy .NET setup
How to setup:
- Add nuget
PM> Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
- Configure JWT settings (for example in appsettings.json)
"Jwt": {
"Issuer": "https://joydipkanjilal.com/",
"Audience": "https://joydipkanjilal.com/",
"Key": "This is a sample secret key - please don't use in production environment.'"
}
- Configure authentication in the Program.cs (or Startup.cs) file
builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; });
- Configure Auth services
builder.Services.AddAuthorization();
...
app.UseAuthentication();
app.UseAuthorization();
Setup is finished, you are ready for authentication implementation!
I recommend [this][1] article to get started with JWT auth in .NET.
More about JWT in common - [2].
<h1>gRPC Auth</h1>
According to [Documentation][3], you can configure authentication/authorization in gRPC services through for these services.
> Interceptors are a gRPC concept that allows apps to interact with
> incoming or outgoing gRPC calls. They offer a way to enrich the
> request processing pipeline.
In other words you have to:
- create new AuthInterceptor
- override `AsyncUnaryCall` method with authentication logic
Also check similar [question][4] on stackoverflow with token setup on grpcClient.
[1]: https://www.infoworld.com/article/3669188/how-to-implement-jwt-authentication-in-aspnet-core-6.html
[2]: https://jwt.io/introduction
[3]: https://learn.microsoft.com/en-us/aspnet/core/grpc/interceptors?view=aspnetcore-7.0
[4]: https://stackoverflow.com/questions/68442239/c-sharp-grpc-client-interceptor-set-authorization-header
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论