上一章快速陳述了自定義驗證功能添加的過程,我的第一個netcore2.2 api項目搭建(三) 但是並沒有真正的去實現,這一章將要實現驗證功能的添加。 這一章實現目標三:jwt認證授權添加 在netcore2.2中,只要添加很簡單的配置就能添加jwt功能了。至於jwt本身是啥大家自行去瞭解,這裡不做 ...
上一章快速陳述了自定義驗證功能添加的過程,我的第一個netcore2.2 api項目搭建(三)
但是並沒有真正的去實現,這一章將要實現驗證功能的添加。
這一章實現目標三:jwt認證授權添加
在netcore2.2中,只要添加很簡單的配置就能添加jwt功能了。至於jwt本身是啥大家自行去瞭解,這裡不做多說了。。
1.1添加JwtHelper類
public class JwtHelper { public const string Audience = "JH.OPEMR.API"; public const string Issuer = "all"; public const string SigningKey = "my first security key"; public static string CreateJwtToken(string uid, string uName, string sub) { var dateTime = DateTime.UtcNow; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SigningKey)); var tokenHandler = new JwtSecurityTokenHandler(); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(new Claim[] { new Claim(JwtClaimTypes.Audience,Audience), new Claim(JwtClaimTypes.Issuer,Issuer), new Claim(JwtClaimTypes.Id, uid), new Claim(JwtClaimTypes.Name, uName), new Claim("Role", sub)//高亮,很重要 }), Expires = dateTime.AddHours(0.5), SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature) }; var token = tokenHandler.CreateToken(tokenDescriptor); var tokenString = tokenHandler.WriteToken(token); return tokenString; } }
這個類就一個方法,提供生成加密的jwt串
1.2在Startup做配置:
//註冊預設認證方式,這裡使用jwt方式 services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(o => { o.TokenValidationParameters = new TokenValidationParameters { RoleClaimType = JwtClaimTypes.Role,//這個很重要 ValidIssuer = JwtHelper.Issuer, ValidAudience = JwtHelper.Audience, IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(JwtHelper.SigningKey)) /***********************************TokenValidationParameters的參數預設值***********************************/ // RequireSignedTokens = true, // SaveSigninToken = false, // ValidateActor = false, // 將下麵兩個參數設置為false,可以不驗證Issuer和Audience,但是不建議這樣做。 // ValidateAudience = true, // ValidateIssuer = true, // ValidateIssuerSigningKey = false, // 是否要求Token的Claims中必須包含Expires // RequireExpirationTime = true, // 允許的伺服器時間偏移量 // ClockSkew = TimeSpan.FromSeconds(300), // 是否驗證Token有效期,使用當前時間與Token的Claims中的NotBefore和Expires對比 // ValidateLifetime = true }; });
可以看出,JwtHelper里的幾個變數在Startup中也使用了,這樣就保證了配置的參數和生成jwt串的參數保持了一致,這樣就能起到防偽作用了,不是千千萬萬個jwt串在咱系統都能通過,如果都通過了,那不是搞笑麽。。。
1.3啟用驗證
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } //啟用驗證 app.UseAuthentication(); //啟用驗證中間件 //app.UseMiddleware<MyAutoMiddleware>(); //啟用Swagger app.UseSwagger(); app.UseSwaggerUI(options => { options.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); }); app.UseMvc(); }
在前一章中,咱們並沒有調用app.UseAuthentication(),是因為上一章咱們自己啟用了中間件,並沒有啟用2.2註入的驗證方式。而這一章,咱們註入了jwt,就得調用這句話是執行驗證授權了。一旦啟用,jwt就會自行進行請求的驗證功能,不需要咱們在寫代碼了。。。
ok,F5運行
可以看到,未驗證,調用失敗。。
咱們先用postman調用login模擬登錄,生成一個jwt串,代碼很簡單:
/// <summary> /// Account 模塊 /// </summary> [Route("api/[controller]/[action]")] [ApiController] public class AccountController : ControllerBase { [HttpGet] public ActionResult<string> Login(long Uid, string UName, string Sub) { if (string.IsNullOrWhiteSpace(Uid.ToString()) || string.IsNullOrWhiteSpace(UName)) throw new Exception("填寫正確用戶"); var tokenString = JwtHelper.CreateJwtToken(Uid.ToString(), UName, Sub); return tokenString; } }
這裡我們得到jwt字元串,將這個字元串添加到header中,再用postman調用get試試:
Headers添加 Authorization ,值:Bearer +jwt串,在Bearer後有個空格記住。
ok了,是不是很簡單,到這裡jwt簡單的認證授權其實已經加完了,後面可以根據各種許可權去維護就好了。。。
至此,第三個目標完成!
既然添加了認證授權,那麼第二章swagger部分就得也加入該功能了,這個很簡單,只要在swagger里做配置就ok了。
//添加header身份驗證信息 var security = new Dictionary<string, IEnumerable<string>> { { "Bearer", new string[] { } }, }; options.AddSecurityRequirement(security); options.AddSecurityDefinition("Bearer", new ApiKeyScheme { Description = "JWT授權(數據將在請求頭中進行傳輸) 參數結構: \"Authorization: Bearer {token}\"", Name = "Authorization",//jwt預設的參數名稱 In = "header", Type = "apiKey" });
F5運行,可以看見加了鎖
點擊Authorize,然後配置下:
再來調用get:
調用成功,可以看到header發送了剛剛添加的jwt串。
至此,整個netcore api項目簡單搭建已經完成!
不過,按這種驗證寫法,突然想到,如果前端被劫持了jwt串,然後其他應用在此jwt串有效期內利用該jwt串調用api,不是也能調通嗎??如果這樣,不是很危險嗎,竟然被別人給瞎調用了,這裡留下了深深的思考,不知道大家都是怎麼做的。。知情者可否留下解決方式,膜拜!!!