JWT(Json Web Token)
jwt是一種用于身份驗(yàn)證的開放標(biāo)準(zhǔn),他可以在網(wǎng)絡(luò)之間傳遞信息,jwt由三部分組成:頭部,載荷,簽名。頭部包含了令牌的類型和加密算法,載荷包含了用戶的信息,簽名則是對頭部和載荷的加密結(jié)果。
jwt鑒權(quán)驗(yàn)證是指在用戶登錄成功后,服務(wù)器生成一個jwt令牌并返回給客戶端,客戶端在后續(xù)的請求中攜帶該令牌,服務(wù)通過令牌的簽名來確定用戶的身份和權(quán)限。這種方式可以避免在每個請求中都需要進(jìn)行身份驗(yàn)證,提高了系統(tǒng)的性能和安全性。
jwt具有以下優(yōu)點(diǎn):
1.無狀態(tài):jwt令牌包含了所有必要的信息,服務(wù)器不需要再每個請求中都進(jìn)行身份驗(yàn)證,避免了服務(wù)器存儲會話信息的開銷。
2.可擴(kuò)展性:jwt令牌可以包含任意的信息,可以根據(jù)需要添加自定義的字段。
3.安全性:jwt令牌使用簽名來保證數(shù)據(jù)的完整性和真實(shí)性,防止數(shù)據(jù)被篡改或偽造。
4.跨平臺:jwt令牌是基于json格式的,可以再不同的變成語言和平臺之間進(jìn)行傳遞和解析。
如何在webapi中使用JWT?
1.首先在項(xiàng)目中添加如下兩個包
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package System.IdentityModel.Tokens.Jwt
也可以直接在Nuget包管理工具中搜索
2.創(chuàng)建JwtOptions模型類,同時在appsetting.json中添加對應(yīng)配置
public class JwtOptions { /// <summary> /// 簽發(fā)者 /// </summary> public string Issuer { get; set; } /// <summary> /// 接收者 /// </summary> public string Audience { get; set; } /// <summary> /// 密鑰 /// </summary> public string Key { get; set; } /// <summary> /// 過期時間 /// </summary> public int ExpireSeconds { get; set; } }
"JWT": { "Issuer": "簽發(fā)方", "Audience": "接受方", "Key": "A86DA130-1B95-4748-B3B2-1B6AA9F2F743",//加密密鑰 "ExpireSeconds": 600 //密鑰過期時間 }
3.創(chuàng)建JWTExtensions靜態(tài)類,添加AddJWTAuthentication擴(kuò)展方法
public static class JWTExtensions { public static AuthenticationBuilder AddJWTAuthentication(this IServiceCollection services, JwtOptions jwtOptions) { return services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(x => { x.TokenValidationParameters = new() { ValidateIssuer = true,//是否驗(yàn)證發(fā)行商 ValidateAudience = true,//是否驗(yàn)證受眾者 ValidateLifetime = true,//是否驗(yàn)證失效時間 ValidateIssuerSigningKey = true,//是否驗(yàn)證簽名鍵 ValidIssuer = jwtOptions.Issuer, ValidAudience = jwtOptions.Audience, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.Key)) }; }); } }
4.創(chuàng)建SwaggerGenOptionsExtensions靜態(tài)類,添加AddAuthenticationHeader擴(kuò)展方法,為swagger增加Authentication報文頭
?
public static class SwaggerGenOptionsExtensions { /// <summary> /// 為swagger增加Authentication報文頭 /// </summary> /// <param name="option"></param> public static void AddAuthenticationHeader(this SwaggerGenOptions option) { option.AddSecurityDefinition("Authorization", new OpenApiSecurityScheme { Description = "Authorization header. \r\nExample:Bearer 12345ABCDE", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.ApiKey, Scheme = "Authorization" } ); ; option.AddSecurityRequirement(new OpenApiSecurityRequirement() { { new OpenApiSecurityScheme { Reference=new OpenApiReference { Type=ReferenceType.SecurityScheme, Id="Authorization" }, Scheme="oauth2", Name="Authorization", In=ParameterLocation.Header, }, new List<string>() } }); } }
5.創(chuàng)建IJwtService接口及實(shí)現(xiàn)JwtService類,其為構(gòu)建token服務(wù)
public interface IJwtService { string BuildToken(IEnumerable<Claim> claims, JwtOptions options); }
public class JwtService : IJwtService { public string BuildToken(IEnumerable<Claim> claims, JwtOptions options) { //過期時間 TimeSpan timeSpan = TimeSpan.FromSeconds(options.ExpireSeconds);//token過期時間 var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(options.Key));//加密的token密鑰 var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);//簽名證書,其值為securityKey和HmacSha256Signature算法 var tokenDescriptor = new JwtSecurityToken(options.Issuer, options.Audience, claims, expires: DateTime.Now.Add(timeSpan), signingCredentials: credentials);//表示jwt token的描述信息,其值包括Issuer簽發(fā)方,Audience接收方,Claims載荷,過期時間和簽名證書 return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);//使用該方法轉(zhuǎn)換為字符串形式的jwt token返回 } }
6.將上述服務(wù)盡數(shù)注冊
builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddScoped<IJwtService, JwtService>(); JwtOptions jwtOpt = builder.Configuration.GetSection("JWT").Get<JwtOptions>(); builder.Services.AddJWTAuthentication(jwtOpt); builder.Services.Configure<SwaggerGenOptions>(c => { c.AddAuthenticationHeader(); }); var app = builder.Build(); app.UseSwagger(); app.UseSwaggerUI(); app.UseHttpsRedirection(); app.UseAuthentication();//注意,一定得先啟動這個 app.UseAuthorization(); //以下回答來自GPT //app.UseAuthentication()是啟用身份驗(yàn)證中間件,它會驗(yàn)證請求中的身份信息,并將身份信息存儲在HttpContext.User屬性中。而app.UseAuthorization()是啟用授權(quán)中間件,它會檢查HttpContext.User中的身份信息是否有訪問當(dāng)前請求所需的權(quán)限。 //一定要先啟用身份驗(yàn)證中間件再啟用授權(quán)中間件,因?yàn)槭跈?quán)中間件需要使用身份驗(yàn)證中間件存儲的身份信息來進(jìn)行權(quán)限驗(yàn)證。如果沒有啟用身份驗(yàn)證中間件,授權(quán)中間件將無法獲取到身份信息,從而無法進(jìn)行權(quán)限驗(yàn)證。 app.MapControllers(); app.Run();
7.在控制器中添加[ApiController]特性開啟jwt鑒權(quán),在登錄接口中返回token
[ApiController] [Route("[controller]/[action]")] [Authorize] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; private readonly ILogger<WeatherForecastController> _logger; //jwt服務(wù) private readonly IJwtService _jwtService; private readonly IConfiguration _configuration; public WeatherForecastController(ILogger<WeatherForecastController> logger, IJwtService jwtService, IConfiguration configuration) { _logger = logger; _jwtService = jwtService; _configuration = configuration; } [HttpGet] public IEnumerable<WeatherForecast> Get() { return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }) .ToArray(); } //AllowAnonymous允許匿名訪問 [AllowAnonymous, HttpGet] public string GetToken() { var jwtopntion = _configuration.GetSection("JWT").Get<JwtOptions>(); List<Claim> claims = new List<Claim>(); claims.Add(new Claim(ClaimTypes.Name, "用戶1")); claims.Add(new Claim(ClaimTypes.Role, "超級管理員")); return _jwtService.BuildToken(claims, jwtopntion); } }
效果測試
?
直接調(diào)用Get方法返回401,鑒權(quán)失敗
?
?調(diào)用GetToken方法,取得token
?點(diǎn)擊右上角綠色按鈕
?value中輸入的值為bearer,空一格,加上之前取得的token,點(diǎn)擊授權(quán)
文章來源:http://www.zghlxwxcb.cn/news/detail-468215.html
?調(diào)用成功文章來源地址http://www.zghlxwxcb.cn/news/detail-468215.html
到了這里,關(guān)于如何在.net6webapi中配置Jwt實(shí)現(xiàn)鑒權(quán)驗(yàn)證的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!