引言
引用依赖包
Microsoft.AspNetCore.Authentication.JwtBearer
System.IdentityModel.Tokens.Jwt
添加身份认证相关服务到容器中
在 Startup.cs 文件 ConfigureServices 方法中 添加服务
services.AddAuthentication(x=>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(jwtOptions =>
{
byte[] btKey = Encoding.UTF8.GetBytes(AppSettingHelper.JsonWebTokenDto.Secret);
SecurityKey securityKey = new SymmetricSecurityKey(btKey);
jwtOptions.TokenValidationParameters = new TokenValidationParameters
{
IssuerSigningKey = securityKey,
//将用于检查令牌的发行者是否与此发行者相同。
ValidIssuer = AppSettingHelper.JsonWebTokenDto.Issuer,
//是否验证发行者
ValidateIssuer = AppSettingHelper.JsonWebTokenDto.ValidateIssuer,
//检查令牌的受众群体是否与此受众群体相同。
ValidAudience = AppSettingHelper.JsonWebTokenDto.Audience,
//在令牌验证期间验证受众 .
ValidateAudience = AppSettingHelper.JsonWebTokenDto.ValidateAudience,
//验证生命周期
ValidateLifetime = true,
// The signing key must match!
//是否调用对签名securityToken的SecurityKey进行验证。
ValidateIssuerSigningKey = true,
// If you want to allow a certain amount of clock drift, set that here:
ClockSkew = TimeSpan.Zero
};
});
swagger 中配置JWT
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Name = "Authorization",
Type = SecuritySchemeType.ApiKey,
Scheme = "Bearer",
BearerFormat = "JWT",
In = ParameterLocation.Header,
Description = "Token(Bearer)令牌" //JWT Authorization header using the Bearer scheme.
});
//swagger 每次请求 Authorization
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string[] {}
}
});
开启中间件
在 Startup.cs 文件中的 Configure 方法中 开启中间件
app.UseAuthentication();
注意:放在 app.UseAuthorization()前边
生成Token
public string CreateToken(TeacherDto dto)
{
var claims = new Claim[]
{
new Claim(JwtRegisteredClaimNames.Sub, dto.UserName), //用户
new Claim(JwtRegisteredClaimNames.Jti, dto.Id.ToString()), //编号
new Claim(nameof(dto.Name), dto.Name) //名字
};
// Create the JWT and write it to a string
byte[] btKey = Encoding.UTF8.GetBytes(AppSettingHelper.JsonWebTokenDto.Secret);
SecurityKey securityKey = new SymmetricSecurityKey(btKey);
DateTime dtNow = DateTime.Now;
var jwt = new JwtSecurityToken(
issuer: AppSettingHelper.JsonWebTokenDto.Issuer,
audience: AppSettingHelper.JsonWebTokenDto.Audience,
claims: claims,
notBefore: dtNow,
expires: dtNow.AddMinutes(AppSettingHelper.JsonWebTokenDto.Expires),
signingCredentials: new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256));
//IdentityModelEventSource.ShowPII = true;
var token = new JwtSecurityTokenHandler().WriteToken(jwt);
return token;
}
获取claims中的参数信息
1、Startup 构造函数中将默认映射方式给移除掉
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
2、使用此命令获取值
HttpContext.User.FindFirst(d => d.Type == JwtRegisteredClaimNames.Sub)?.Value;
接口中添加[Authorize()]
jwt 自定义策略
1、新建 xxxRequirement类,继承IAuthorizationRequirement
2、新建 xxxAuthorizationHandler ,继承AuthorizationHandler<xxxRequirement>,重写 HandleRequirementAsync方法
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, JsonWebTokenRequirement requirement)
{
//是否经过验证
var isAuthenticated = context?.User?.Identity?.IsAuthenticated ?? false;
if (!isAuthenticated)
{
context.Fail(); // 显式的声明验证失败
}
else
{
context.Succeed(requirement); // 显式的声明验证成功
}
return Task.CompletedTask;
}
3、Startup.cs 文件 ConfigureServices 方法添加 自定义策略服务
services.AddAuthorization(auth =>
{
auth.AddPolicy("Bearer", policy => policy.Requirements.Add(new Service.Authorization.JsonWebTokenRequirement()));
});
services.AddSingleton<IAuthorizationHandler, Service.Authorization.JsonWebTokenHandler>();
4、接口添加 [Authorize(Policy = “Bearer”)]