91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ASP.NET Core 中jwt授權認證的示例分析

發布時間:2021-07-02 10:09:51 來源:億速云 閱讀:180 作者:小新 欄目:開發技術

這篇文章將為大家詳細講解有關ASP.NET Core 中jwt授權認證的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

1,快速實現授權驗證

什么是 JWT ?為什么要用 JWT ?JWT 的組成?

這些百度可以直接找到,這里不再贅述。

實際上,只需要知道 JWT 認證模式是使用一段 Token 作為認證依據的手段。

我們看一下 Postman 設置 Token 的位置。

ASP.NET Core 中jwt授權認證的示例分析

那么,如何使用 C# 的 HttpClient 訪問一個 JWT 認證的 WebAPI 呢?

ASP.NET Core 中jwt授權認證的示例分析

下面來創建一個 ASP.NET Core 項目,嘗試添加 JWT 驗證功能。

1.1 添加 JWT 服務配置

在 Startup.cs 的 ConfigureServices 方法中,添加一個服務

  // 設置驗證方式為 Bearer Token
   // 你也可以添加 using Microsoft.AspNetCore.Authentication.JwtBearer;
   // 使用 JwtBearerDefaults.AuthenticationScheme 代替 字符串 "Brearer"
   services.AddAuthentication("Bearer")
    .AddJwtBearer(options =>
    {
     options.TokenValidationParameters = new TokenValidationParameters
     {
      ValidateIssuerSigningKey = true,
      IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("abcdABCD1234abcdABCD1234")), // 加密解密Token的密鑰

      // 是否驗證發布者
      ValidateIssuer = true,
      // 發布者名稱
      ValidIssuer = "server", 

      // 是否驗證訂閱者
      // 訂閱者名稱
      ValidateAudience = true,
      ValidAudience = "client007",

      // 是否驗證令牌有效期
      ValidateLifetime = true,
      // 每次頒發令牌,令牌有效時間
      ClockSkew = TimeSpan.FromMinutes(120)
     };
    });

修改 Configure 中的中間件

app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();  // 注意這里
app.UseAuthorization();

就是這么簡單,通過以上設置,要求驗證請求是否有權限。

1.2 頒發 Token

頒發的 Token ,ASP.NET Core 不會保存。

ASP.NET Core 啟用了 Token 認證,你隨便將生成 Token 的代碼放到不同程序的控制臺,只要密鑰和 Issuer 和 Audience 一致,生成的 Token 就可以登錄這個 ASP.NET Core。

也就是說,可以隨意創建控制臺程序生成 Token,生成的 Token 完全可以登錄 ASP.NET Core 程序。

至于原因,我們后面再說,

在 Program.cs 中,添加一個這樣的方法

  static void ConsoleToke()
  {

   // 定義用戶信息
   var claims = new Claim[]
   {
    new Claim(ClaimTypes.Name, "癡者工良"),
    new Claim(JwtRegisteredClaimNames.Email, "66666666666@qq.com"),
   };

   // 和 Startup 中的配置一致
   SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("abcdABCD1234abcdABCD1234"));

   JwtSecurityToken token = new JwtSecurityToken(
    issuer: "server",
    audience: "client007",
    claims: claims,
    notBefore: DateTime.Now,
    expires: DateTime.Now.AddMinutes(30),
    signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256)
   );

   string jwtToken = new JwtSecurityTokenHandler().WriteToken(token);
   Console.WriteLine(jwtToken);
  }

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。

ASP.NET Core 中jwt授權認證的示例分析

發現報 401 (無權限)狀態碼,這是因為請求時不攜帶令牌,會導致不能訪問 API。

從控制臺終端復制生成的 Token 碼,復制到 Postman 中,再次訪問,發現響應狀態碼為 200,響應成功。

ASP.NET Core 中jwt授權認證的示例分析

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(); 的源代碼各種使用了一個項目來寫,代碼比較多。要理解這兩個中間件的作用,我們不妨來手動實現他們的功能。

解析出的 Token 是一個 ClaimsPrincipal 對象,將此對象給 context.User 賦值,然后在 API 中可以使用 User 實例來獲取用戶的信息。

在中間件中,使用下面的代碼可以獲取客戶端請求的 Token 解析。

context.RequestServices.GetRequiredService<IAuthenticationService>().AuthenticateAsync(context, JwtBearerDefaults.AuthenticationScheme);

那么,我們如何手工從原生的 Http 請求中,解析出來呢?且看我慢慢來分解步驟。

首先創建一個 TestMiddleware 文件,作為中間件使用。

 public class TestMiddleware
 {
  private readonly RequestDelegate _next;
  jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
  public TestMiddleware(RequestDelegate next)
  {
   _next = next;
  }
  public async Task Invoke(HttpContext context)
  {
   if (context == null)
   {
    throw new ArgumentNullException(nameof(context));
   }

   // 我們寫代碼的區域


   // 我們寫代碼的區域
   await _next(context);
  }
 }

2.1.1 從 Http 中獲取 Token

下面代碼可以中 http 請求中,取得頭部的 Token 。

當然,客戶端可能沒有攜帶 Token,可能獲取結果為 null ,自己加個判斷。

貼到代碼區域。

 string tokenStr = context.Request.Headers["Authorization"].ToString();

Header 的 Authorization 鍵,是由 Breaer {Token}組成的字符串。

2.1.2 判斷是否為有效令牌

拿到 Token 后,還需要判斷這個 Token 是否有效。

因為 Authorization 是由 Breaer {Token}組成,所以我們需要去掉前面的 Brear 才能獲取 Token。

 /// <summary>
  /// Token是否是符合要求的標準 Json Web 令牌
  /// </summary>
  /// <param name="tokenStr"></param>
  /// <returns></returns>
  public bool IsCanReadToken(ref string tokenStr)
  {
   if (string.IsNullOrWhiteSpace(tokenStr) || tokenStr.Length < 7)
    return false;
   if (!tokenStr.Substring(0, 6).Equals(Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme))
    return false;
   tokenStr = tokenStr.Substring(7);
   bool isCan = jwtSecurityTokenHandler.CanReadToken(tokenStr);

   return isCan;
  }

獲得 Token 后,通過 JwtSecurityTokenHandler.CanReadToken(tokenStr); 來判斷 Token 是否符合協議規范。

將下面判斷貼到代碼區域。

if (!IsCanReadToken(ref tokenStr))
    return ;

2.1.3 解析 Token

下面代碼可以將 Header 的 Authorization 內容轉為 JwtSecurityToken 對象。

(截取字符串的方式很多種,喜歡哪個就哪個。。。)

 /// <summary>
  /// 從Token解密出JwtSecurityToken,JwtSecurityToken : SecurityToken
  /// </summary>
  /// <param name="tokenStr"></param>
  /// <returns></returns>
  public JwtSecurityToken GetJwtSecurityToken(string tokenStr)
  {
   var jwt = jwtSecurityTokenHandler.ReadJwtToken(tokenStr);
   return jwt;
  }

不過這個 GetJwtSecurityToken 不是我們關注的內容,我們是要獲取 Claim。

JwtSecurityToken.Claims

將下面代碼貼到代碼區域

JwtSecurityToken jst = GetJwtSecurityToken(tokenStr);
IEnumerable<Claim> claims = jst.Claims;

2.1.4 生成 context.User

context.User 是一個 ClaimsPrincipal 類型,我們通過解析出的 Claim,生成 ClaimsPrincipal。

JwtSecurityToken jst = GetJwtSecurityToken(tokenStr);
IEnumerable<Claim> claims = jst.Claims;

List<ClaimsIdentity> ci = new List<ClaimsIdentity>() { new ClaimsIdentity(claims) };
context.User = new ClaimsPrincipal(ci);

最終的代碼塊是這樣的

   // 我們寫代碼的區域
   string tokenStr = context.Request.Headers["Authorization"].ToString();
   string requestUrl = context.Request.Path.Value;
   if (!IsCanReadToken(ref tokenStr))
    return;
   JwtSecurityToken jst = GetJwtSecurityToken(tokenStr);
   IEnumerable<Claim> claims = jst.Claims;
   List<ClaimsIdentity> ci = new List<ClaimsIdentity>() { new ClaimsIdentity(claims) };

   context.User = new ClaimsPrincipal(ci);
   var x = new ClaimsPrincipal(ci);
   // 我們寫代碼的區域

2.2 實現校驗認證

app.UseAuthentication(); 的大概實現過程已經做出了說明,現在我們來繼續實現 app.UseAuthorization(); 中的功能。

繼續使用上面的中間件,在原代碼塊區域添加新的區域。

// 我們寫代碼的區域

// 我們寫的代碼塊

 22.2.1 Endpoint

Endpoint 標識了一個 http 請求所訪問的路由信息和 Controller 、Action 及其特性等信息。

[Authorize] 特性繼承了 IAuthorizeData[AllowAnonymous] 特性繼承了 IAllowAnonymous

以下代碼可以獲取所訪問的節點信息。

var endpoint = context.GetEndpoint();

那么如何判斷所訪問的 Controller 和 Action 是否使用了認證相關的特性?

 var authorizeData = endpoint?.Metadata.GetOrderedMetadata<IAuthorizeData>() ?? Array.Empty<IAuthorizeData>();

Metadata 是一個 ASP.NET Core 實現的集合對象,GetOrderedMetadata<T> 可以找出需要的特性信息。

這個集合不會區分是 Contrller 還是 Action 的 [Authorize] 特性。

那么判斷 是否有 [AllowAnonymous] 特性,可以這樣使用。

if (endpoint?.Metadata.GetMetadata<IAllowAnonymous>() != null)
   {
    await _next(context);
    return;
   }

關于“ASP.NET Core 中jwt授權認證的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

进贤县| 商丘市| 寿宁县| 西丰县| 武平县| 垦利县| 吉首市| 天台县| 北宁市| 剑河县| 青阳县| 南皮县| 太白县| 陆良县| 桦南县| 富民县| 丹阳市| 曲水县| 陈巴尔虎旗| 罗城| 兴化市| 綦江县| 民和| 太谷县| 江阴市| 衡东县| 拉孜县| 板桥市| 临洮县| 吉木萨尔县| 左权县| 广平县| 体育| 广灵县| 新宾| 三台县| 章丘市| 邹城市| 通山县| 昌邑市| 青浦区|