JWT的封装
需要安装两个包。
包1:System.IdentityModel.Tokens.Jwt
Install-Package System.IdentityModel.Tokens.Jwt
包2:Microsoft.AspNetCore.Authentication.JwtBearer
Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
我们创建一个类用于存放密钥和过期时间。
public class JWTSettings
{
public string SecKey { get; set; }
public int ExpireSeconds { get; set; }
}
在appsettings.json文件中对密钥和过期时间进行定义
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"JWT": {
"SecKey": "awfasgjiowqpuurio12352opoijaops12", //密钥(这里瞎写的)
"ExpireSeconds": 3600//过期时间
}
}
在Program.cs中配置,从appsettings.json中取出密钥和过期时间。
builder.Services.Configure<JWTSettings>(builder.Configuration.GetSection("JWT"));
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(opt =>
{
var jwtSettings = builder.Configuration.GetSection("JWT").Get<JWTSettings>();
byte[] keyBytes = Encoding.UTF8.GetBytes(jwtSettings.SecKey);
var secKey = new SymmetricSecurityKey(keyBytes);
opt.TokenValidationParameters = new()
{
ValidateIssuer=false,
ValidateAudience=false,
ValidateLifetime=true,
ValidateIssuerSigningKey=true,
IssuerSigningKey=secKey
};
});
app.UseCors();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
创建一个类生成JWT,调用将生成的JWT返回,这里时写死了。
List<Claim> claims = new List<Claim>();
claims.Add(new Claim("userName", "张三"));
claims.Add(new Claim(ClaimTypes.Role, "admin"));//颁发管理员角色
string key = jwtSettingsOpt.Value.SecKey;
DateTime expire = DateTime.Now.AddSeconds(jwtSettingsOpt.Value.ExpireSeconds);
byte[] secBytes = Encoding.UTF8.GetBytes(key);
var seckey = new SymmetricSecurityKey(secBytes);
var credentials = new SigningCredentials(seckey, SecurityAlgorithms.HmacSha256Signature);
var tokenDescriptor = new JwtSecurityToken(claims: claims, expires: expire, signingCredentials: credentials);
string jwt = new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
return jwt;
[Authorize]的使用
对方法进行[Authorize]标识,那么这个方法就必须要在JWT检验通过了才能使用,也就是在使用该方法时需要传输后端生成的JWT,否则就调用不了[Authorize]标识的方法。
这里创建一个带有[Authorize]标识的web api,该方法会返回调用人的姓名也就是张三。
[Authorize]
[HttpPost]
public object Bdd()
{
return this.User.FindFirst("userName")!.Value;
}
如果我们不带后端生成的JWT发送请求,那么我们可以看到会有401的错误。
只有我们将生成的JWT带上向后端发送请求,才能调用请求。
调用必须要在请求头中带参数,格式为:
Authorization:Bearwe+一个空格+后端生成的JWT
如下面这种格式:
现在我们带JWT发送请求,我们看到返回了张三给我们。
在上面我们配置了这样一段代码,这是用于管理员授权的。
claims.Add(new Claim(ClaimTypes.Role, "admin"));
我们现在对web api进行一下升级,[Authorize(Roles ="admin")]表示只有JWT中带有Role为admin的才能对其访问也就是配置上面段代码配置后生成的JWT生效。
[Authorize(Roles = "admin")]//配置只有管理员角色才能请求
[HttpPost]
public object Cdd()
{
return this.User.FindFirst("userName")!.Value;
}