AspNetCore 成长杂记(一):JWT授权鉴权之生成JWT(其二)
引子
前面说了用第三方类库生成JWT的故事,给我带来了很大的方便,并且我也承诺要写一篇用常规方法生成JWT的文章(一般都是用微软官方的类库),因此才有了这篇文章。
另外,在前面的文章中,我要纠正一下一些错误JWT的整个结构决定了JWT只能作为临时的授权认证解决方案,如果对用户的机密性要求比较高,必须用有状态控制管理的解决方案,JWT只能作为一般性方案使用,它的应用场合主要是由多个WebAPI构成的多进程多线程多接口这样的微服务架构,是为了解决使用状态管理带来的不便才应用而生,一般JWT必须和HTTPS配合才会具有安全性。这是因为JWT作为一种可被破解的数据,只有TLS加密后,才不会被真正破解。
在微软的Indentiy认证框架中(我个人感觉应该叫ASP.NET Core Indentity),MVC和WebAPI虽然使用不同的Nuget包,但本质是一样的……废话不多说了,直接正题开始:有请我们的主角:JwtSecurityTokenHandler(从名字中就知道它和数据库操作有关,JWT中的数据一般都是来自用户数据库,helper一般用来表示资源管理),后面我们会通过它来实现JWT的生成。
实施
和前面一样,我们这里主要讲解最常用的非对称算法的JWT,这里采用的算法是RSA,当然你也可以采用其他算法来达到目标。
首先需要安装nuget包Microsoft.AspNetCore.Authentication.JwtBearer
,当然,有的文章会让你安装一个System.IdentityModel.Tokens.JWT
的包,这个完全不需要,因为前面的包已经包含后者了,你只要在引用包以后,构建一下工程,在dubug目录里面找到项目生成文件,就会发现这个dll被放进去了。
由于ASP.NET Core是以依赖注入为主的,而这个包作为一个Service(服务),需要使用其自身提供的扩展方法来注入ASP.NET Core 的WebApplication的Service对象(IOC容器)中进行集中管理。
点击查看实现代码
builder.Services.AddAuthentication()..AddJwtBearer(jwtOptions =>{
jwtOptions.Authority = "https://jwtserver.test.net";
//jwtOptions.Audience = "jwtresouce";
jwtOptions.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = builder.Configuration["Jwt:Issuer"],//发行者
ValidAudience = builder.Configuration["Jwt:Audience"], //订阅者
IssuerSigningKey = new RsaSecurityKey(RSA.Create(2048)) //jwt签名算法
};
})
- 先创建一个用来生成JWT的
JwtSecurityTokenHandler
对象,为后面的工作提供基础 - 再创建一个数组,用来存放用户信息
- 创建
SecurityTokenDescriptor
对象,设置JWT的加密算法,有效期等属性 - 调用之前创建的
JwtSecurityTokenHandler
对象的CreateToken
方法,创建一个令牌对象,再调用WriteToken
方法,获得到字符串格式的JWT - 返回结果
点击查看实现代码
[HttpPost]
public string CreateJwtSecurityToken()
{
var tokenHandler = new JwtSecurityTokenHandler();
var mookdata = new Dictionary<string, string>();
mookdata[ClaimTypes.Name] = "John Doe";
mookdata[ClaimTypes.Email] = "johndoe@example.com";
mookdata[ClaimTypes.Role] = "vistor";
var claims = new Claim[mookdata.Count - 1];
foreach (var item in mookdata)
{
for (int i = 0; i < claims.Length; i++)
{
claims[i] = new Claim(item.Key, item.Value);
}
}
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.UtcNow.AddDays(7),
SigningCredentials = new SigningCredentials(new RsaSecurityKey(RSA.Create(2048)),
SecurityAlgorithms.RsaSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
return tokenString;
}
总结
上述讲到的方法一般都是比较常用的方法(这个好像是来自微软官方文档),先对于上篇文章,它相对比较灵活,不会涉及到x509证书的问题,而且解决方案比较多,容易应用。
关于生成JWT,我也是简单的了解和使用,因此层次不少太深,如果读者在其中发现了问题,也欢迎各位提出宝贵的意见,谢谢。
关于JWT,我想说这只是WebAPI授权鉴权的开端,不是终点,如果有时间,我会再写一篇结合JWT来授权鉴权的文章,来更好的理解JWT的应用,希望我的文章会给您带来帮助,让我们一起期待吧!