c# - 直接从令牌获取 JWT 声明,ASP Net Core 2.1
问题描述
我正在研究 ASP Net Core 2.1 Web API。我已经在我的项目中成功实现了 JWT。授权的一切工作正常。
通常,当我需要用户声明时,我知道我可以像这样得到它们(例如电子邮件声明):
var claimsIdentity = User.Identity as ClaimsIdentity;
var emailClaim = claimsIdentity.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Email);
问题是,我不在从ControllerBase
类继承的控制器中,所以我没有任何User
对象或[Authorize]
属性。
我所拥有的是令牌本身。
例如
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbiIsIm5iZiI6MTU2ODYzNjYxMywiZXhwIjoxNTY4NjQ3NDEzLCJpYXQiOjE1Njg2MzY2MTN9.ED9x_AOvkLQqutb09yh3Huyv0ygHp_i3Eli8WG2S9N4
我想直接从令牌中获取声明,因为:
- 我可以访问令牌。
- 我不在 Controller 类中,请求没有经过任何
[Authorize]
属性,所以IHttpContextAccessor
也不能使用。
如何在 ASP Net Core 2.1 中实现这一点?如果有人想看看我如何添加用户声明:
var tokenDescriptor = new SecurityTokenDescriptor
{
Expires = DateTime.UtcNow.AddHours(3),
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, email),
new Claim(ClaimTypes.Email, email)
}),
SigningCredentials = new SigningCredentials(key: new SymmetricSecurityKey(key), algorithm: SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
我位于派生自IDocumentFilter
(Swagger 类)的类中
解决方案
这是一个简单的解决方法:
var tokenDescriptor = new SecurityTokenDescriptor
{
Expires = DateTime.UtcNow.AddHours(3),
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, "user@hotmail.com"),
new Claim(ClaimTypes.Email, "user@hotmail.com")
}),
SigningCredentials = new SigningCredentials(key: new SymmetricSecurityKey(key), algorithm: SecurityAlgorithms.HmacSha256Signature)
};
var Securitytoken = new JwtSecurityTokenHandler().CreateToken(tokenDescriptor);
var tokenstring = new JwtSecurityTokenHandler().WriteToken(Securitytoken);
var token = new JwtSecurityTokenHandler().ReadJwtToken(tokenstring);
var claim = token.Claims.First(c => c.Type == "email").Value;
return claim;
推荐阅读
- bash - 如何让这个脚本在不使用 find 的情况下删除当前目录和子目录中的零长度文件?
- flutter - 在 CustomScrollView 中使用 PageView
- xcode - 模拟器中没有可用的 Iphone 设备
- c - 如何修复类型参数与类型参数不兼容
- python - 用python检查文件夹
- rust - 如何在模块内部使用 const?
- javascript - Steam 市场 API 的跨域读取阻止
- html - 如何设置引导进度条最大值 300?
- android - 应用程序未在 Android 4.4 和 5.1 上运行
- python-asyncio - 在运行 aiohttp 循环之前创建数据库连接