在两个 asp 核心 api 之间共享 Jwt 令牌

Posted

技术标签:

【中文标题】在两个 asp 核心 api 之间共享 Jwt 令牌【英文标题】:Share Jwt token between two asp core api 【发布时间】:2020-01-31 20:10:47 【问题描述】:

我在这里遇到了麻烦。 我正在尝试构建第二个 asp 核心 api,它将共享一个创建的 jwt 令牌购买我的主要 aspcore api aka:授权服务器。 但我无法让它工作。

我的想法是我的 Angular 客户端将从我的主 api(授权服务器)获取令牌并发送相同的令牌以从另一个 api 获取数据,该 api 必须与身份验证服务器检查我猜令牌是否有效.

我认为这是配置选项中的某处:

            .AddJwtBearer(options =>
            
                options.TokenValidationParameters = new TokenValidationParameters
                
                    ValidateIssuer = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = Configuration["Jwt:Issuer"],
                    ValidAudience = Configuration["Jwt:Audience"],
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])),
                           // Ensure the token audience matches our audience value (default true):
                    ValidateAudience = true,

                ;

我的配置文件中有:

  "Jwt": 
    "Key": "METAPRODUCTIQUE2904",
    "Audience": "http://localhost:52771/",
    "Issuer": "http://localhost:52771",
  ,

然后主应用程序在端口 52771 上运行以进行测试,我当前的辅助应用程序在端口 52772 上运行 但我认为我做错了什么但不知道是什么 我非常感谢你们的一些想法

【问题讨论】:

您在使用身份服务器吗?否则我会建议这样做。这是一个很好的介绍,与您尝试完成的场景类似:https://youtu.be/KmrTO3__Huw,文档位于http://docs.identityserver.io/en/latest/ 【参考方案1】:

首先,让我们看看它是如何工作的。

1) user ---------------------(Get Token) ---------------------> AuthServer
2) AuthServer -----------------(Token)------------------------> user
3) user ----------(Request with Token as auth header)---------> OtherServers

在第 2 步中,AuthServer 检查用户权限并创建一个包含用户信息、权限和其他内容的数据包,然后使用您提供给我们称之为 base64 字符串的key 对其进行加密Token.

我们在其他服务器中也有key。当请求到达他们时,他们首先尝试使用key 对其进行解密。如果一切顺利,现在另一台服务器拥有用户信息和权限以及其他内容。

所以AuthServer不需要连接到其他服务器,它们可以互相工作。

在这两个服务的startup 类中,您应该有以下代码:

 public void ConfigureServices(IServiceCollection services)
        
            ...
            // JWT
            services.AddAuthentication(x =>
            
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            ).AddJwtBearer(x =>
            
                x.RequireHttpsMetadata = false;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters
                
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII
                        .GetBytes("MySpecialKey")),
                    ValidIssuer = "MainServer",
                    ValidAudience = "Sample",
                    ValidateIssuer = false,
                    ValidateAudience = false
                ;
            );
            ...
        

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        
            ...
            app.UseAuthentication();
            ...
        

authorization server 的一项服务中,您应该实现一种为注册用户生成令牌的方法:

public async Task<string> GenToken()
        
            // check if the user has the required permissions
            ....

            // authentication successful so generate jwt token
            var tokenHandler = new JwtSecurityTokenHandler();
            var tokenDescriptor = new SecurityTokenDescriptor
            
                Subject = new ClaimsIdentity(new Claim[]
                
                    new Claim(ClaimTypes.Name, "Username"),
                ),
                Expires = DateTime.UtcNow.AddDays(1),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII
                    .GetBytes("MySpecialKey")), SecurityAlgorithms.HmacSha256Signature)
            ;
            var token = tokenHandler.CreateToken(tokenDescriptor);
            var tokenString = tokenHandler.WriteToken(token);

            return tokenString;
        

现在您可以在控制器或 API 之上使用 [Authorize] 属性。

[Authorize] 控制器或API 的每个请求都应包含一个标头,其键为Authorization,值为bearer USERTOKEN

【讨论】:

我已经做到了,但无法让第二台服务器到达第一台....我们可以通过邮件交换更多信息或在 *** 上向我发送私人消息吗?很高兴 我已将答案更新为包含逻辑。服务器不需要连接,因为身份验证正在使用加密来完成这项工作。 谢谢 amin,但是例如,您将 ValidIssuer = "MainServer"、ValidAudience = "Sample" 的值设置为什么,例如 localhost:52771 和 localhost:52772 或者只是简单的每个键?跨度> 这些值是可选的,你可以放任何东西,关键是你可以在其他服务器上解密令牌后验证它们。

以上是关于在两个 asp 核心 api 之间共享 Jwt 令牌的主要内容,如果未能解决你的问题,请参考以下文章

如何在使用 JWT 的 asp.net 核心 web 应用和 web api 中使用谷歌身份验证

使用 JWT 令牌保护 asp.net 核心 Web api 时如何从 Azure AD 获取用户

asp.net 核心中的 jwt 令牌无效

在后端(.Net)和前端(角度)之间共享 JWT 令牌

uri查询参数中的asp.net核心JWT?

JWT 和 asp.net(核心)Web 应用程序