在单独的 Web Api 上进行 JWT 验证

Posted

技术标签:

【中文标题】在单独的 Web Api 上进行 JWT 验证【英文标题】:JWT Validation on separate web Api 【发布时间】:2021-01-31 10:34:06 【问题描述】:

我有一个核心 3.1 web api 是 Vur.js 客户端,它使用 JWT 令牌来保证安全。这一切都很好。我现在必须向解决方案添加第二个 Web api。我的问题是当客户端访问第二个 Web api 并发送它从第一个接收到的令牌时,我将如何验证该令牌?我真的不想建认证服务器。

回答 Chetan Ranpariya

try 
    var tokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
    tokenHandler.ValidateToken(token, new TokenValidationParameters 
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(key),
        ValidateIssuer = false,
        ValidateAudience = false,
        ClockSkew = TimeSpan.Zero
    , out SecurityToken validatedToken);

    var jwtToken = (JwtSecurityToken)validatedToken;
    var accountId = int.Parse(jwtToken.Claims.First(x => x.Type == "id").Value);

    // attach account to context on successful jwt validation
    context.Items["Account"] = await dataContext.Accounts.FindAsync(accountId);

【问题讨论】:

第一个 Web 应用如何验证令牌? 为什么不能在第二个API中使用这个方法? 我想我可以,但我需要一种将客户端的“秘密”传递给第二个 API 的方法。每个客户端都有自己的秘密,在他们进行身份验证时生成。 【参考方案1】:

我的问题是当客户端访问第二个 web api 并发送 它从第一个收到的令牌,我将如何验证 令牌?

在第二个 WebAPI 应用程序中,您可以参考以下步骤来验证 JWT Token:

    添加 nuget 包“Microsoft.AspNetCore.Authentication.JwtBearer”

    在 Startup.cs 文件中添加以下命名空间

     using Microsoft.IdentityModel.Tokens;    
     using Microsoft.AspNetCore.Authentication.JwtBearer;    
     using System.Text;  
    

    在 Startup 类中创建一个新函数来注册 JWT 服务,然后在“ConfigureServices”方法中调用此函数。我们正在告诉框架如何检查请求是否被授权。

     public void ConfigureServices(IServiceCollection services)
     
         SetupJWTServices(services);
         services.AddControllers();
     
     private void SetupJWTServices(IServiceCollection services)
     
         string key = "ThisismySecretKey"; //this should be same which is used while creating token      
         var issuer = "Test.com";  //this should be same which is used while creating token  
    
         services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
       .AddJwtBearer(options =>
       
           options.TokenValidationParameters = new TokenValidationParameters
           
               ValidateIssuer = true,
               ValidateAudience = true,
               ValidateIssuerSigningKey = true,
               ValidIssuer = issuer,
               ValidAudience = issuer,
               IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key))
           ;
    
           options.Events = new JwtBearerEvents
           
               OnAuthenticationFailed = context =>
               
                   if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                   
                       context.Response.Headers.Add("Token-Expired", "true");
                   
                   return Task.CompletedTask;
               
           ;
       );
     
    

    [注意] JWT Key 和 Issuer 必须与创建 token 时使用的相同。

    在“配置”方法中添加“app.UseAuthentication()”

         app.UseAuthentication();
         app.UseAuthorization();
    

    在Controller或Action方法的头部添加“Authorize”属性。

     [ApiController]
     [Route("[controller]")]
     [Authorize]
     public class WeatherForecastController : ControllerBase
     
        ....
     
    

然后,使用 JWT 令牌测试应用程序:

参考:ASP.NET Core Web API - Creating And Validating JWT (JSON Web Token)

【讨论】:

这很好,除了我没有静态密钥(秘密)。每个用户都会动态生成他们的密钥(每个用户都有不同的密钥) 我终于选择了这个效果很好的解决方案 - 谢谢

以上是关于在单独的 Web Api 上进行 JWT 验证的主要内容,如果未能解决你的问题,请参考以下文章

Simplemembership ASPXAUTH cookie 在两个单独的 Web 项目上进行验证

NET Core 3.1 MVC 授权/身份验证,带有在单独的 Net Core 3.1 Web Api 中从外部获取的令牌 (JWT)

客户端是不是应该在每条路由上进行身份验证? [关闭]

在 C# Web api 上进行用户身份验证的最佳实践是啥?

.NET Core Web API 密钥

使用 JWT 对单独的 API 微服务进行身份验证