我正在开发 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
我想直接从令牌获取声明,因为:
[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, "[email protected]"),
new Claim(ClaimTypes.Email, "[email protected]")
}),
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;
这是提取声明的简单方法:
public IEnumerable<Claim> ExtractClaims(string jwtToken)
{
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
JwtSecurityToken securityToken = (JwtSecurityToken)tokenHandler.ReadToken(jwtToken);
IEnumerable<Claim> claims = securityToken.Claims;
return claims;
}
例如,在我当前的项目中,我通过验证获得声明。它的刷新令牌,所以我不能使用[Authorize]属性。
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
public ClaimsPrincipal ValidateRefreshToken(string refreshToken)
{
try
{
var validationParams = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(tokenSecurityKey),
ValidateLifetime = true
};
return new JwtSecurityTokenHandler().ValidateToken
(
refreshToken,
validationParams,
out SecurityToken token
);
}
catch (Exception e)
{
Log.Error(e.Message);
return null;
}
}
然后
var claims = ValidateRefreshToken(refreshToken);
...
var userIdString = claims.Claims.FirstOrDefault(x => x.Type == "userId")?.Value;
检查这是否有帮助 -
if(claim.Type == "用户名") uname = Claim.Value;