Authentication 如何为微服务和用户传递JWT
我正在构建一个基于微服务架构的系统。这些微服务是使用Asp.NETCore3.1创建的 简化的高级图表如下所示: 我希望系统中有两个安全级别: 微服务认证 当ApiGateway接收到请求时,它会从InternalAuthService接收“微服务JWT”,并在通过http向其他微服务发送请求时将该JWT包含在授权标头中。此JWT包含一个或多个声明,微服务使用这些声明来决定是接受还是拒绝请求 InternalAuthService是使用IdentityServer实现的,现在它似乎工作得很好。这意味着如果ApiGateway没有向JWT提供所需声明,CustomerService将拒绝请求 用户身份验证 接下来,我想添加用户身份验证,这就是我需要您帮助的地方。ApiGateway中的一些端点不需要用户身份验证(例如用户注册和用户登录)。但许多其他端点将需要用户身份验证。我很确定is可以解决这个问题,就像我在其他项目中做的那样 因为我过去在构建小型单片应用程序时使用过IdentityFramework,所以我也希望在这个系统中使用IdentityFramework。这就是我引入UserAuthService的原因 当用户未提供有效的“用户JWT”时,我想拒绝ApiGateway中的请求。此JWT还将包含许多声明,用于根据用户的角色限制对CustomerService端点的访问 问题 当从ApiGateway向CustomerService发送请求时,“microservice JWT”被放置在授权头中。JWT在CustomerService的Starup.cs文件中经过身份验证,如下所示:Authentication 如何为微服务和用户传递JWT,authentication,asp.net-core,jwt,authorization,microservices,Authentication,Asp.net Core,Jwt,Authorization,Microservices,我正在构建一个基于微服务架构的系统。这些微服务是使用Asp.NETCore3.1创建的 简化的高级图表如下所示: 我希望系统中有两个安全级别: 微服务认证 当ApiGateway接收到请求时,它会从InternalAuthService接收“微服务JWT”,并在通过http向其他微服务发送请求时将该JWT包含在授权标头中。此JWT包含一个或多个声明,微服务使用这些声明来决定是接受还是拒绝请求 InternalAuthService是使用IdentityServer实现的,现在它似乎工作得很好。
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "https://localhost:44308"; //url pointing to InternalAuthService
options.RequireHttpsMetadata = false;
options.Audience = "customer_service"; //the claim required by the CustomerService
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
}
我想以类似的方式设置“用户JWT”的身份验证,但我不知道如何进行
因此,第一个问题是,我可以在哪里/如何在请求中存储“用户JWT”,以便在CustomerService收到该请求时能够对其进行授权
下一个问题是,如何设置“用户JWT”的身份验证
如果IdentityServer能让事情变得更简单,我愿意用IdentityFrameWork代替IdentityFrameWork(但我更愿意这样做,因为正如我提到的,我有使用IdentityFrameWork的经验)。我的观点:这种安全体系结构很复杂。通过使用单用户令牌和基于声明的授权,您可以实现所需的两个安全级别 如果使用用户令牌对网关进行调用,网关将基于用户令牌对调用进行身份验证,检索“userId”声明,并将其注入到微服务的下游调用中。为了实现这一点,理想情况下,userId需要是服务操作路径中的一个组件 因此,给定资源在网关上公开的URI为:
GET /resources/{resourceId}
但在实际服务中暴露为:
GET /resources/{userId}/{resourceId}
这意味着下游微服务可以实施自己的措施来阻止访问。例如,拒绝请求资源所有者以外的任何人访问该资源的请求
这一点如下所示:
如果服务路径修改是一个困难的短期更改,那么用户声明注入可以作为查询、头、甚至是主体参数来完成 我的观点:这种安全架构很复杂。通过使用单用户令牌和基于声明的授权,您可以实现所需的两个安全级别 如果使用用户令牌对网关进行调用,网关将基于用户令牌对调用进行身份验证,检索“userId”声明,并将其注入到微服务的下游调用中。为了实现这一点,理想情况下,userId需要是服务操作路径中的一个组件 因此,给定资源在网关上公开的URI为:
GET /resources/{resourceId}
但在实际服务中暴露为:
GET /resources/{userId}/{resourceId}
这意味着下游微服务可以实施自己的措施来阻止访问。例如,拒绝请求资源所有者以外的任何人访问该资源的请求
这一点如下所示:
如果服务路径修改是一个困难的短期更改,那么用户声明注入可以作为查询、头、甚至是主体参数来完成 按照您的建议,当微服务相互通信时(不会因到达ApiGateway的请求而触发),这不会消除安全性吗?服务内调用仍然需要在用户上下文中进行。我不知道这是否足够安全。这对于我们的全球销售平台来说已经足够了,因为这是我们使用的架构。无论如何,我们通过了上次审计。听起来像是经过了战斗测试;)我一定会考虑你的建议,谢谢你的宝贵意见!尽管如此,我还是想为最初的问题找到一个解决方案,因为如果我决定这样做的话,我对如何实现这一点很感兴趣。按照你的建议,当微服务相互通信时(不会因为到达ApiGateway的请求而被触发),这不会消除安全性吗?服务内呼叫仍需要在用户上下文中进行。我不知道这是否足够安全。这对于我们的全球销售平台来说已经足够了,因为这是我们使用的架构。无论如何,我们通过了上次审计。听起来像是经过了战斗测试;)我一定会考虑你的建议,谢谢你的宝贵意见!尽管如此,如果我决定这样做,我还是会为最初的问题找到一个解决方案,因为我对如何实现它感兴趣。