.NET CORE集成JWT(一)
JWT(JSON Web Token)和 identityserver4是目前最流行的跨域身份验证解决方案。具体介绍这里就不做阐述了。下面是进行JWT的demo案例分析。
1、 先下载JWT在.NET中的程序包
microsoft.aspnetcore.authentication.jwtbearer
2、JWT的相关配置:可以写在appsettings.json中或者写在类中
/// <summary>
/// JWT配置类:一般生产环境都是从配置文件读取
/// 常量只读
/// </summary>
public class configureM
{
/// <summary>
/// 密钥
/// </summary>
public const string IssuerSigningKey = "6Zi/5pifUGx1c+mYv+aYn1BsdXPpmL/mmJ9QbHVz6Zi/5pifUGx1c+mYv+aYn1BsdXPpmL/mmJ9QbHVz6Zi/5pifUGx1c+mYv+aYn1BsdXPpmL/mmJ9QbHVz6Zi/5pifUGx1cw==";
/// <summary>
/// 时钟偏移
/// </summary>
public const int ClockSkew = 5;
/// <summary>
/// Audience
/// </summary>
public static string ValidAudience = "https://blog.csdn.net/weixin_44352179";//动态更新验证
/// <summary>
/// Issuer
/// </summary>
public const string ValidIssuer = "ShiPlus";
/// <summary>
/// 到期时间
/// </summary>
public const int Expires = 5;
}
3、 Startup.cs添加JWT验证的相关配置
//在ConfigureServices方法中加入
//JWT
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,//是否在令牌验证期间验证Issuer
ValidateAudience = true,//是否在令牌验证期间验证Audience
ValidateLifetime = true,//是否验证失效时间
ClockSkew = TimeSpan.FromSeconds(Convert.ToInt32(configureM.ClockSkew)),//设置在验证时间时应用的时钟偏差。
ValidateIssuerSigningKey = true,//是否调用对 securityToken 签名的SecurityKey 的验证
ValidAudience = configureM.ValidAudience,//用于检查令牌的受众的有效受众
ValidIssuer = configureM.ValidIssuer,//检查令牌的颁发者的有效颁发者
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configureM.IssuerSigningKey))//签名验证的SecurityKey
};
});
services.AddAuthorization();
//Configure方法中加入
//jwt添加
app.UseAuthentication();
app.UseAuthorization();
4、添加API控制器,创建生成Token的api
[Route("api/[controller]")]
[ApiController]
public class TokenAuthController : ControllerBase
{
/// <summary>
/// 获取token
/// </summary>
/// <remarks></remarks>
/// <param name="username">admin</param>
/// <param name="password">123</param>
/// <returns></returns>
[HttpGet]
[Route("Token")]
public string GenerateTokenAsync(string username, string password)
{
if (username == "admin" && password == "123")
{
//每次登陆动态刷新
configureM.ValidAudience = username + password + DateTime.Now.ToString();
var claims = new[] {
new Claim(ClaimTypes.Name, username),
//自定义参数,key可以任意定义
new Claim(ClaimTypes.Email, "211962258@qq.com"),
new Claim(JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(DateTime.Now.AddMinutes(configureM.Expires)).ToUnixTimeSeconds()}"),
new Claim(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}")
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configureM.IssuerSigningKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var securityToken = new JwtSecurityToken(
issuer: configureM.ValidIssuer,//颁发者
audience: configureM.ValidAudience,//接收者
claims: claims,//自定义参数
expires: DateTime.Now.AddMinutes(Convert.ToInt32(configureM.Expires)),//token失效时间
signingCredentials: creds); //签名证书
var token = new JwtSecurityTokenHandler().WriteToken(securityToken);
return token;
}
else
{
throw new Exception("账号密码错误");
}
}
}
5、添加数据访问API:AuthorizeTest是需要授权才可访问的,AllowAnonymousTest是可以直接可以访问的。
/// <summary>
/// 带有授权的请求[Authorize]
/// </summary>
/// <returns></returns>
[HttpGet]
[Authorize]
[Route("AuthorizeTest")]
public string AuthorizeTest()
{
return "我是返回结果,需要授权";
}
/// <summary>
/// 任何人都可访问[AllowAnonymous]
/// </summary>
/// <returns></returns>
[HttpGet]
[AllowAnonymous]
[Route("AllowAnonymousTest")]
public string AllowAnonymousTest()
{
return "我是返回结果";
}
运行API项目进行测试接口,这里可以集成swagger,进行联合使用非常方便和直观。下一篇问题会具体实现jwt+swagger。这里可以先用postman进行测试。
- 测试调用AllowAnonymousTest方法,会正常返回
- 测试调用AuthorizeTest方法,会报401未授权错误
- 这时候需要先调用生成token的API,拿着token作为请求头再次去请求AuthorizeTest方法(Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9lbWFpbGFkZHJlc3MiOiIyMTE5NjIyNThAcXEuY29tIiwiZXhwIjoxNjMwMzA3MTAyLCJuYmYiOiIxNjMwMzA2ODAyIiwiaXNzIjoiU2hpUGx1cyIsImF1ZCI6ImFkbWluMTIzMjAyMS84LzMwIDE1OjAwOjAyIn0.29t8WLeT0iTPngNycayOWTP0-5ply4MeE7808uQT7wc),这次应该会返回正常。
6、Token过期时间
生成Token时设置了token过期时间为5分钟(为了快速看到效果,token时效写的很短)。五分钟后再去请求AuthorizeTest方法时,会报401未授权错误。
★下篇文章会讲到★:
JWT授权+Swagger联合使用;
如何获取token中的自定义参数如:用户名等;
如何强制token失效;