【问题标题】:How to pass a JWT for a microservice and for a user如何为微服务和用户传递 JWT
【发布时间】:2020-05-07 16:24:15
【问题描述】:

我正在构建一个基于微服务架构的系统。微服务是使用 Asp.Net Core 3.1 创建的。

一个简化的高级图如下所示:

我想在系统中设置两个级别的安全性:

微服务认证

当 ApiGateway 收到请求时,它会从 InternalAuthService 接收“微服务 JWT”,并在通过 http 向其他微服务发送请求时将此 JWT 包含在授权标头中。此 JWT 包含一个或多个声明,微服务使用这些声明来决定是否应接受或拒绝请求。

InternalAuthService 是使用 IdentityServer 实现的,现在它似乎工作得很好。这意味着如果 ApiGateway 未向 JWT 提供所需声明,则 CustomerService 将拒绝请求。

用户认证

接下来,我想添加用户身份验证,这就是我需要您帮助的地方。 ApiGateway 中的一些端点不需要用户认证(例如,用户注册和用户登录)。但是许多其他端点将需要用户身份验证。我很确定可以解决这个问题,就像我在其他项目中所做的那样。

因为我过去在构建小型单体应用程序时使用过 IdentityFramework,所以我也想在这个系统中使用它。这就是我引入 UserAuthService 的原因。

当用户未提供有效的“用户 JWT”时,我想拒绝 ApiGateway 中的请求。此 JWT 还将包含许多声明,用于根据用户拥有的角色限制对 CustomerService 端点的访问。

问题

当从 ApiGateway 向 CustomerService 发送请求时,“微服务 JWT”被放置在授权标头中。 JWT 在 CustomerService 的 Starup.cs 文件中进行身份验证,如下所示:

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”的身份验证?

如果 IdentityFrameWork 可以让事情变得更容易,我愿意用 IdentityServer 代替它(但我不希望这样做,因为正如我所提到的,我有使用 IdentityFramework 的经验)。

【问题讨论】:

    标签: authentication asp.net-core jwt authorization microservices


    【解决方案1】:

    我的观点:这种安全架构很复杂。您可以通过使用单个用户令牌和基于声明的授权来实现所需的两个安全级别。

    如果使用用户令牌对网关进行调用,网关会根据用户令牌对调用进行身份验证,检索“userId”声明,并将其注入到微服务的下游调用中。为了使这项工作正常工作,理想情况下,userId 需要成为服务操作路径中的一个组件。

    因此,在网关上为给定资源公开的 URI 是:

    GET /resources/{resourceId}
    

    但在实际服务中暴露为:

    GET /resources/{userId}/{resourceId}
    

    这意味着下游微服务可以实施自己的措施来阻止访问。例如,拒绝来自所请求资源的所有者以外的任何人访问资源的请求。

    这里有说明:

    如果服务路径修改是一项困难的短期更改,那么用户声明注入可以作为查询、标头甚至正文参数来完成。

    【讨论】:

    • 按照您的建议,当微服务相互通信时(不会因为请求到达 ApiGateway 而被触发),这不会消除安全性吗?
    • 服务内调用仍然需要在用户的上下文中进行。我不知道这是否足够安全。这对我们的全球销售平台来说已经足够了,因为这是我们使用的架构。无论如何,我们通过了上一次审计。
    • 听起来它已经过实战测试;)我一定会考虑您的建议,感谢您的有用意见!不过,如果我决定这样做,我会为原始问题提供一个解决方案,因为我对如何实现它感兴趣。
    猜你喜欢
    • 2020-05-31
    • 2020-04-05
    • 1970-01-01
    • 2020-08-03
    • 2019-08-12
    • 2019-07-09
    • 2018-03-17
    • 2020-07-06
    • 2018-07-15
    相关资源
    最近更新 更多