如何验证请求标头、JWT 令牌

Posted

技术标签:

【中文标题】如何验证请求标头、JWT 令牌【英文标题】:How to authenticate request header, JWT token 【发布时间】:2019-09-16 19:50:44 【问题描述】:

我有 Angular 7 前端项目和 asp.net 核心 Web API。

从 Web API 创建 JWT Web 令牌后,我返回到fronted,它将保存在本地存储中。 在我想向 Web API 发送请求后,我会将 JWT Web 令牌放入请求标头部分。

这样就可以了。所以我想使用 JWT 有效负载数据对请求进行身份验证。我的 JWT 有效负载数据有记录用户名、用户角色的一些信息。

我想在通过 http get 请求获取产品详细信息时检查它的有效令牌。你能帮我在 asp.net core web api 中进行身份验证吗?

asp.net 核心 web api,Angular 7 cli

Startup.cs - WEB API

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
 
  options.TokenValidationParameters = new TokenValidationParameters
  
  ValidateIssuer = true,
  ValidateAudience = true,
  ValidateLifetime = true,
  ValidateIssuerSigningKey = true,
  ValidIssuer = Configuration["Jwt:Issuer"],
  ValidAudience = Configuration["Jwt:Issuer"],
  IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
 ;
);

services.AddMvc();

构建 Web 令牌 - WEB API

private string BuildToken(MYWebApi.Models.CustomerModel user)

  var claims = new[] 
  new Claim(JwtRegisteredClaimNames.NameId,user.CusId.ToString()),
  new Claim(JwtRegisteredClaimNames.Sub,user.CusName),
  new Claim(JwtRegisteredClaimNames.Email,user.CusEmail),
  new Claim("role","user"),
;

 var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
 var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

 var token = new JwtSecurityToken(_config["Jwt:Issuer"],
  _config["Jwt:Issuer"],
 claims,
 expires: DateTime.Now.AddMinutes(30),
 signingCredentials: creds);

 return new JwtSecurityTokenHandler().WriteToken(token);

将令牌放入标题部分 - FRONT END

 @Injectable( )
    export class TokenInterceptorService implements HttpInterceptor

      constructor(private injector:Injector)  

      intercept(req, next)
        let serverService = this.injector.get(ServerService)
        let tokenizedReq = req.clone(
            setHeaders:
              Autherization:`Bearer $serverService.getToken()`
            
         )
        return next.handle(tokenizedReq)
      
    

控制器 - WEB API

[Route("GetProduct")]
        [HttpGet]
        public List<ProductModel> GetProduct(int productId)
        
            var repo = new MEData.Repository.ProductRepo();

            var productData = repo.GetProduct(productId);

            return productData;
        

【问题讨论】:

你似乎已经设置好了,据我所知,你所需要的只是控制器或操作方法上的 Authorize 属性 我试过了。但随后它将所有请求显示为 401(未经授权)请求。 理想情况下,这就是您想要的行为,以保护您的 api。但是,如果您只有某些需要授权的操作,则只需使用 Authorize 属性标记这些操作 你有什么日志? 我没有得到你的想法朋友。你是什​​么意思'日志'? 【参考方案1】:

除了app.UseAuthentication() 呼叫之外,请尝试以下选项:

1.[Authorize] 属性与AuthenticationSchemes 一起应用

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Route("GetProduct")]
[HttpGet]
public List<ProductModel> GetProduct(int productId)

   //...

另外,请尝试在ConfigureServices中添加以下行

services.AddAuthorization();

2. 尝试将services.AddAuthorization 与策略和选定方案一起使用

services.AddAuthorization(options =>

    options.AddPolicy("Jwt", policy =>
    
        policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
        policy.RequireAuthenticatedUser();
    );
);

然后使用[Authorize]属性的策略

[Authorize(Policy = "Jwt")]
[Route("GetProduct")]
[HttpGet]
public List<ProductModel> GetProduct(int productId)

   //...

一般来说,我认为services.AddAuthorization 行是必需的。看看哪些选项适合您。

【讨论】:

【参考方案2】:

确保在 Startup 类的 Configure 方法中 app.UseMvc(); 之前添加了 app.UseAuthentication(); 代码

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        

            app.UseAuthentication();

            app.UseMvc();
        

然后根据您的要求在操作或控制器级别添加[Authorize]attribute

【讨论】:

那么唯一的原因可能是 jwt 令牌无效。您是否尝试过使用jwt.io 解码令牌? web api 是否可以在不申请授权的情况下返回数据? 为了测试尝试在 Startup.cs 中设置ValidateIssuer = false, ValidateAudience = false, 相同结果的朋友。

以上是关于如何验证请求标头、JWT 令牌的主要内容,如果未能解决你的问题,请参考以下文章

使用 Rails 和 React 时如何在标头中获取 JWT 令牌

如果用于身份验证的 JWT 令牌保存在 HTTP-Only cookie 中,您如何从 cookie 中读取它以便我可以将其包含在请求标头中?

如何在客户端上保存 JWT 令牌,在节点中使用 Hapi js。?

如何使用标头中的用户 JWT 令牌转发授权并将其与 cookie 中的 JWT 令牌进行比较以验证用户?

如何向每个标头添加 json Web 令牌?

如何在 api 网关架构中获取 JWT 令牌