.NET Core的JWT認證的學習

今天學習下JWT,遇到了兩個坑爹問題,這裏記錄下。在 ASP.NET Core 中,受權的設置方式有兩種,可使用角色,也可使用策略,這裏也將簡單舉例角色、策略的使用。html

JWT這裏不作介紹,若是想了解更多,請看https://www.jianshu.com/p/a12fc67c9e05,https://www.cnblogs.com/CreateMyself/p/11123023.html ,這兩篇都講解的很好,這裏只寫實際的使用和遇到的問題。git

1. JWT的SecretKey必須16位以上

jwt中key必須16位以上,不然長度不夠會拋出異常,異常代碼以下github

System.ArgumentOutOfRangeException
  HResult=0x80131502
  Message=IDX10603: Decryption failed. Keys tried: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
Exceptions caught:
 '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
token: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]' 
  Source=Microsoft.IdentityModel.Tokens
  StackTrace:
   at Microsoft.IdentityModel.Tokens.SymmetricSignatureProvider..ctor(SecurityKey key, String algorithm, Boolean willCreateSignatures)
....................

2.獲取token以後,一直401Unauthorized

在Startup.cs中的Configure中添加app.UseAuthentication();新建立.net core項目的時候,會自動添加受權app.UseAuthorization();可是JWT實際上是一種認證,準確;來講是登陸的過程,須要用戶名和密碼的認證。算法

例如:你要登錄論壇,輸入用戶名張三,密碼1234,密碼正確,證實你張三確實是張三,這就是 認證authentication;那麼是否有刪除添加等的操做,這就是受權authorizationjson

3.JWTtoken的獲取

  
//appsettings.json中增長配置信息
"JwtSettings": { "Issuer": "https://localhost:44378/", "Audience": "https://localhost:44378/", "SecretKey": "1234567890123456" }
// Startup.cs中增長JWT的設置           
services.AddAuthentication(options => { //認證middleware配置 options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(o => { //主要是jwt token參數設置 o.TokenValidationParameters = new TokenValidationParameters { //Token頒發機構 ValidIssuer = jwtSettings.Issuer, //頒發給誰 ValidAudience = jwtSettings.Audience, //這裏的key要進行加密,須要引用Microsoft.IdentityModel.Tokens IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecretKey)), ValidateIssuerSigningKey = true, //是否驗證Token有效期,使用當前時間與Token的Claims中的NotBefore和Expires對比 ValidateLifetime = true, //容許的服務器時間偏移量 ClockSkew = TimeSpan.Zero }; });
// Controller中獲取token       
[HttpPost]
public IActionResult Token(LoginModel login) { _logger.LogInformation($"獲取Token:User:{login.User}"); if (string.IsNullOrEmpty(login.User) || string.IsNullOrEmpty(login.Password))//判斷帳號密碼是否正確 { return BadRequest(); } var claim = new List<Claim>{ new Claim(ClaimTypes.Name,login.User), new Claim(ClaimTypes.Role,"Test") }; //創建增長策略的受權 if (login.User == "Test") claim.Add(new Claim("Test", "Test")); if (login.User == "Test1") claim.Add(new Claim("Test", "Test1")); if (login.User == "Test2") claim.Add(new Claim("Test", "Test2")); if (login.User == "Test3") claim.Add(new Claim("Test", "Test3")); //對稱祕鑰 var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey)); //簽名證書(祕鑰,加密算法) var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); //生成token [注意]須要nuget添加Microsoft.AspNetCore.Authentication.JwtBearer包,並引用System.IdentityModel.Tokens.Jwt命名空間 var token = new JwtSecurityToken(_jwtSettings.Issuer, _jwtSettings.Audience, claim, DateTime.Now, DateTime.Now.AddMinutes(30), creds); return Ok(new { token = new JwtSecurityTokenHandler().WriteToken(token) }); }

 

4.基於角色的受權

        [HttpGet]
        [Authorize(Roles ="Test")]
        public ActionResult<string> AuthValue()
        {
            var name = User.FindFirst(ClaimTypes.Name)?.Value;
            var role = User.FindFirst(ClaimTypes.Role)?.Value;
            _logger.LogInformation($"權限登陸,用戶名:{name},角色:{role}");

            return $"權限登陸,用戶名:{name},角色:{role}";
        }
Roles角色若是有多個,能夠以逗號隔開。

5.基於策略的受權

//Startup.cs中添加策略
services.AddAuthorization(options => { options.AddPolicy("OnlyTestAccess", policy => policy.RequireClaim("Test", new string[] { "Test1", "Test2" })); options.AddPolicy("DepartmentAccess", policy => policy.RequireClaim("Department")); });
        // 方法上增長策略    
[HttpGet] [Authorize(Policy
= "OnlyTestAccess")] public ActionResult<string> AuthExtensionValue() { var name = User.FindFirst(ClaimTypes.Name)?.Value; var role = User.FindFirst(ClaimTypes.Role)?.Value; _logger.LogInformation($"基於策略的登陸,用戶名:{name},角色:{role}"); return $"基於策略的登陸,用戶名:{name},角色:{role}"; }

6.運行的截圖

 

7.Github上的源碼

https://github.com/jasonhua95/samll-project/tree/master/JwtApiDemo服務器

相關文章
相關標籤/搜索