nuget安装:Microsoft.AspNetCore.Authentication.JwtBearer 3.1.0 版本
一、添加配置文件
"Authentication": {
"JwtBearer": {
"IsEnabled": "true",
"SecurityKey": "Demo_C421AAEE0D114E9C1",
"Issuer": "Demo",
"Audience": "Demo",
"Expiration": 60 //token过期时间 (单位:分钟)
}
}
二、添加一个扩展类和jwt配置文件类
public static class AuthConfigure
{
public static void ConfigureJwt(this IServiceCollection services, IConfiguration configuration)
{
if (bool.Parse(configuration["Authentication:JwtBearer:IsEnabled"]))
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = "JwtBearer";
options.DefaultChallengeScheme = "JwtBearer";
}).AddJwtBearer("JwtBearer", options =>
{
options.Audience = configuration["Authentication:JwtBearer:Audience"];
options.TokenValidationParameters = new TokenValidationParameters
{
// The signing key must match!
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(configuration["Authentication:JwtBearer:SecurityKey"])),
// Validate the JWT Issuer (iss) claim
ValidateIssuer = true,
ValidIssuer = configuration["Authentication:JwtBearer:Issuer"],
// Validate the JWT Audience (aud) claim
ValidateAudience = true,
ValidAudience = configuration["Authentication:JwtBearer:Audience"],
// Validate the token expiry
ValidateLifetime = true,
// If you want to allow a certain amount of clock drift, set that here
ClockSkew = TimeSpan.Zero
};
});
}
}
}
public class JwtConfig
{
/// <summary>
/// 密钥
/// </summary>
public string SecurityKey { get; set; }
/// <summary>
/// 所属者
/// </summary>
public string Issuer { get; set; }
public string Audience { get; set; }
/// <summary>
/// 过期时间
/// </summary>
public int Expiration { get; set; }
}
三、配置Startup
public void ConfigureServices(IServiceCollection services)
{
//注入JWT配置文件
services.Configure<JwtConfig>(Configuration.GetSection("Authentication:JwtBearer"));
//var provider = context.Services.BuildServiceProvider();
//var config = provider.GetRequiredService<IOptions<JwtConfig>>().Value;
//配置jwt,函数里面也可以使用上面两行注释掉的代码的方式获取配置
services.ConfigureJwt(Configuration);
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication(); //一定要在这个位置(app.UseAuthorization()上面)
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
四、登录接口
在需要验证的接口上加特性:[Authorize]
private readonly JwtConfig jwtModel = null;
public JwtLoginController(IOptions<JwtConfig> _jwtModel)//注入jwt配置参数
{
jwtModel = _jwtModel.Value;
}
/// <summary>
/// 登录
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<string> Login(LoginDto dto)
{
//一波验证逻辑。。。。。。
//下面代码自行封装
var claims = new List<Claim>();
claims.AddRange(new[]
{
new Claim("UserName", dto.UserName),
new Claim(JwtRegisteredClaimNames.Sub, dto.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.Now.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64)
});
DateTime now = DateTime.UtcNow;
var jwtSecurityToken = new JwtSecurityToken(
issuer: jwtModel.Issuer,
audience: jwtModel.Audience,
claims: claims,
notBefore: now,
expires: now.Add(TimeSpan.FromMinutes(jwtModel.Expiration)),
signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtModel.SecurityKey)), SecurityAlgorithms.HmacSha256)
);
string token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
return token;
}
public class LoginDto
{
public string UserName { get; set; }
public string Password { get; set; }
}