浅谈ASP.NET Core 中jwt授权认证的流程原理

2020-03-19 16:03:24王振洲

Main() 中,调用此方法

 public static void Main(string[] args)
  {
   ConsoleToke();
   CreateHostBuilder(args).Build().Run();
  }

1.3 添加 API访问

我们添加一个 API。

[Authorize] 特性用于标识此 Controller 或 Action 需要使用合规的 Token 才能登录。

 [Authorize]
 [Route("api/[controller]")]
 [ApiController]
 public class HomeController : ControllerBase
 {
  public string Get()
  {
   Console.WriteLine(User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Name));
   return "访问成功";
  }
 }

然后启动 ASP.NET Core,在 Postman 测试 访问 https://localhost/api/home。

发现报 401 (无权限)状态码,这是因为请求时不携带令牌,会导致不能访问 API。

从控制台终端复制生成的 Token 码,复制到 Postman 中,再次访问,发现响应状态码为 200,响应成功。

ASP.NET Core 自带 jwt 认证大概就是这样。

那么,ASP.NET Core 内部是如何实现的呢?又有哪些特性哪些坑呢?请往下看~

2,探究授权认证中间件

在上面的操作中,我们在管道配置了两个中间件。

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

app.UseAuthentication(); 的作用是通过 ASP.NET Core 中配置的授权认证,读取客户端中的身份标识(Cookie,Token等)并解析出来,存储到 context.User 中。

app.UseAuthorization(); 的作用是判断当前访问 Endpoint (Controller或Action)是否使用了 [Authorize]以及配置角色或策略,然后校验 Cookie 或 Token 是否有效。

使用特性设置相应通过认证才能访问,一般有以下情况。

 // 不适用特性,可以直接访问
 public class AController : ControllerBase
 {
  public string Get() { return "666"; }
 }

 /// <summary>
 /// 整个控制器都需要授权才能访问
 /// </summary>
 [Authorize]
 public class BController : ControllerBase
 {
  public string Get() { return "666"; }
 }

 public class CController : ControllerBase
 {
  // 只有 Get 需要授权
  [Authorize]
  public string Get() { return "666"; }
  public string GetB() { return "666"; }
 }

 /// <summary>
 /// 整个控制器都需要授权,但 Get 不需要
 /// </summary>
 [Authorize]
 public class DController : ControllerBase
 {
  [AllowAnonymous]
  public string Get() { return "666"; }
 }

2.1 实现 Token 解析

至于 ASP.NET Core 中,app.UseAuthentication();app.UseAuthorization(); 的源代码各种使用了一个项目来写,代码比较多。要理解这两个中间件的作用,我们不妨来手动实现他们的功能。