環境:.net core 5
項目類型:WebApi
目標:使用Jwt為項目做身份驗證,為了前后端分離開發時保護接口安全。
---------------------------------------------------------------------------------------------------------------------------------------------
第一步:
在Startup.cs文件的ConfigureServices方法中注冊JWT身份驗證服務
services.AddAuthentication(option => { option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; //jwt Bearer默認值 option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; });
然后在Configure中啟用身份驗證
app.UseAuthentication();
注意:需要在app.UseAuthorization();之前啟用身份驗證,因為需要進行身份驗證后才能進行授權。
第二步:
我們需要為JWT配置它所承載的方法,比如我們需要驗證的參數,既然是身份驗證肯定需要驗證參數,和一些事件等,比如身份驗證不通過時等,那我們第二步開始給JWT配置驗證參數。
1 services.AddAuthentication(option => 2 { 3 option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; //jwt Bearer默認值 4 option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; 5 }).AddJwtBearer(option => { 6 option.TokenValidationParameters = new TokenValidationParameters 7 { 8 //是否驗證簽發者 9 ValidateIssuer = true, 10 //簽發者 11 ValidIssuer = "jiaheshangqianfa", 12 //是否驗證接受者 13 ValidateAudience = true, 14 //接受者 15 ValidAudience = "jiaheshangjieshou", 16 //是否驗證簽名密鑰 17 ValidateIssuerSigningKey = true, 18 //簽名密鑰 19 IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes("chuangqianmingyueguang")), 20 ////驗證令牌過期時間 21 ValidateLifetime = true, 22 //令牌安全時是否保存令牌 23 SaveSigninToken = true, 24 //令牌過期時間的偏移值 25 ClockSkew = TimeSpan.FromSeconds(1) 26 }; 27 });
對於簽發者和接受者還有簽名密鑰的參數,在實際開發中,為了方便維護,肯定是寫在配置文件中,這里為了方便理解,就直接賦值了。
JWT的簽名密鑰長度需要符合HS256的規定否則會報錯。
注意:ClockSkew默認時間為5分鍾,如你設置令牌過期時間為5分鍾,那么驗證范圍在10分鍾內,這是一個大坑!!!!!!!!!!!!
第三步:當我們已經可以對JWT令牌進行驗證了,那么接下來肯定就是構造我們的JWT令牌了。
1.創建一個JwtManager,來管理我們的JWT令牌。
using Microsoft.IdentityModel.Tokens; using System; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; namespace JWTDemo { public class JwtManager { public string CreatJwtToken() { //簽名密鑰 string jwtKey = "chuangqianmingyueguang"; //簽發者 string jwtIssuser = "jiaheshangqianfa"; //接收者 string jwtAudience = "jiaheshangjieshou"; //令牌所承載的信息 var claims = new[] { //用戶Id new Claim("Id","userId"), new Claim("Name","userName"), new Claim("Role","userRole") }; //獲取對稱密鑰 var key = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(jwtKey)); //使用has256加密密鑰 var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); //生成token var token = new JwtSecurityToken( //簽發者 jwtIssuser, //接收者 jwtAudience, //jwt令牌數據體 claims: claims, //令牌過期時間 expires: DateTime.Now.AddMinutes(10), //為數字簽名定義SecurityKey signingCredentials: creds ); return "Bearer " + new JwtSecurityTokenHandler().WriteToken(token); } } }
那么我們現在來試試是否能生成JWT令牌了!
我們在項目默認創建的WeatherForecastController控制器中修改GET請求接口來返回一個Jwt令牌。
[HttpGet] public string Get() { JwtManager jwtManager = new JwtManager(); string jwtToken = jwtManager.CreatJwtToken(); return jwtToken; }
啟動項目!!!請求接口!!!
現在我們已經成功拿到JWT令牌,那么我看來看看這個令牌是否正確,復制令牌到Jwt解析看一下(https://jwt.io/ )。
我們需要把令牌的前綴Bearer刪掉,因為Bearer前綴是在我們項目中所需要的規范,然后將我們的簽名密鑰輸入到右下角,左下角提示Signature Verified那么我們的令牌驗證成功!
我們可以看到Jwt令牌分為 Header Payload VerifySignature 三部分。
Header是表示token的類型(Jwt)和加密方式(HS256)。
Payload是我們在令牌中所承載的用戶信息。
VerifySignature是將 Header進行base64加密 + Payload進行64加密 + 簽名密鑰 組成好后進行HS256加密。
第四步:保護接口
我們現在已經有了Jwt令牌,也有了Jwt驗證方案,那么我們怎么對接口進行保護呢,很簡單。
示例:
[HttpPost] [Authorize] public string Test() { return "通過!"; }
我們只需要在接口上方加上 [Authorize] 那么這個接口就需要驗證令牌訪問,我們試試直接訪問這個接口。
很顯然接口提示 401錯誤,我們需要進行身份驗證,在請求頭中加入 Authorization
這里需要對Swagger進行一些配置,使用NuGet安裝Swashbuckle.AspNetCore.Filters
此處直接粘Swagger配置代碼,因為我們的重點在Jwt。
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "JWTDemo", Version = "v1" }); c.OperationFilter<SecurityRequirementsOperationFilter>(); c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme { Description = "JWT授權(數據將在請求頭中進行傳輸) 直接在下框中輸入Bearer {token}(注意兩者之間是一個空格)\"", Name = "Authorization",//jwt默認的參數名稱 In = ParameterLocation.Header,//jwt默認存放Authorization信息的位置(請求頭中) Type = SecuritySchemeType.ApiKey }); });
啟動項目!
我們像之前那樣先拿到Jwt的令牌,復制令牌,然后
可以看到這里Swagger有一個小鎖,將令牌粘貼進去,訪問接口
可以看到我們的接口已經可以訪問通過!
附上Demo鏈接地址:https://gitee.com/lu-qi2166690055/net5-jwt-demo
以上內容均為原創,轉載請注明並帶上鏈接,謝謝。