直接从令牌中获取 JWT 声明,ASP Net Core 2.1

G.D*_*mov 7 c# jwt asp.net-core asp.net-core-webapi

我正在研究 ASP Net Core 2.1 Web API。我已经在我的项目中成功实现了 JWT。具有授权的一切工作正常。

通常,当我需要用户声明时,我知道我可以像这样获得它们(例如电子邮件声明):

var claimsIdentity = User.Identity as ClaimsIdentity;
var emailClaim = claimsIdentity.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Email);
Run Code Online (Sandbox Code Playgroud)

问题是,我不在从ControllerBase类继承的控制器中,所以我没有任何User对象或[Authorize]属性。

我所拥有的是令牌本身。
例如

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbiIsIm5iZiI6MTU2ODYzNjYxMywiZXhwIjoxNTY4NjQ3NDEzLCJpYXQiOjE1Njg2MzY2MTN9.ED9x_AOvkLQqutb09yh3Huyv0ygHp_i3Eli8WG2S9N4
Run Code Online (Sandbox Code Playgroud)

我想直接从令牌中获取声明,因为:

  1. 我可以访问令牌。
  2. 我不在 Controller 类中,并且请求没有通过任何[Authorize]属性,因此IHttpContextAccessor也不能使用。

如何在 ASP Net Core 2.1 中实现这一点?如果有人想看看我如何添加用户声明:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbiIsIm5iZiI6MTU2ODYzNjYxMywiZXhwIjoxNTY4NjQ3NDEzLCJpYXQiOjE1Njg2MzY2MTN9.ED9x_AOvkLQqutb09yh3Huyv0ygHp_i3Eli8WG2S9N4
Run Code Online (Sandbox Code Playgroud)

我位于一个派生自IDocumentFilter(Swagger 类)的类中

Ren*_*ena 6

这是一个简单的解决方法:

    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;
Run Code Online (Sandbox Code Playgroud)


Den*_*sel 6

这是提取声明的简单方法:

public IEnumerable<Claim> ExtractClaims(string jwtToken)
{
    JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
    JwtSecurityToken securityToken = (JwtSecurityToken)tokenHandler.ReadToken(jwtToken);
    IEnumerable<Claim> claims = securityToken.Claims;
    return claims;
}
Run Code Online (Sandbox Code Playgroud)


Vic*_*sov 5

例如,在我当前的项目中,我通过验证获得声明。它的刷新令牌,所以我不能使用 [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;
    }
}
Run Code Online (Sandbox Code Playgroud)

进而

var claims = ValidateRefreshToken(refreshToken);
...
var userIdString = claims.Claims.FirstOrDefault(x => x.Type == "userId")?.Value;
Run Code Online (Sandbox Code Playgroud)