今天學習下JWT,遇到了兩個坑爹問題,這里記錄下,在 ASP.NET Core 中,授權的設定方式有兩種,可以使用角色,也可以使用策略,這里也將簡單舉例角色、策略的使用,
JWT這里不做介紹,如果想了解更多,請看https://www.jianshu.com/p/a12fc67c9e05,https://www.cnblogs.com/CreateMyself/p/11123023.html ,這兩篇都講解的很好,這里只寫實際的使用和遇到的問題,
1. JWT的SecretKey必須16位以上
jwt中key必須16位以上,否則長度不夠會拋出例外,例外代碼如下
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;那么是否有洗掉添加等的操作,這就是授權authorization
3.JWTtoken的獲取
//appsettings.json中增加配置資訊 "JwtSettings": { "Issuer": "https://localhost:44378/", "Audience": "https://localhost:44378/", "SecretKey": "1234567890123456" }View Code
// 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 }; });View Code
// 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) }); }View Code
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/94917.html
標籤:.NET Core
上一篇:三分鐘學會Redis在.NET Core中做快取中間件
下一篇:建議收藏備用:.net core使用QRCoder生成普通二維碼和帶Logo的二維碼詳細使用教程,原始碼已更新至開源模板
