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

Posted

技术标签:

【中文标题】直接从令牌获取 JWT 声明,ASP Net Core 2.1【英文标题】:Get JWT claims directly from the token, ASP Net Core 2.1 【发布时间】:2020-01-17 11:11:40 【问题描述】:

我正在开发一个 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 类)

【问题讨论】:

How to decode JWT Token?的可能重复 投票关闭(作为上述的副本)。不是因为这是一个糟糕的问题,而是因为那里的答案正是你所需要的:) 是的,这解决了我的问题。谢谢 【参考方案1】:

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

    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;

【讨论】:

【参考方案2】:

例如,在我当前的项目中,我通过验证获得索赔。它的刷新令牌,所以我不能使用 [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;

【讨论】:

这是整个网络上唯一对我有帮助的解决方案。谢谢。

以上是关于直接从令牌获取 JWT 声明,ASP Net Core 2.1的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core JWT 和声明

使用 JWT 令牌保护 asp.net 核心 Web api 时如何从 Azure AD 获取用户

如何使用剃刀视图 ASP .Net Core 从 JWT 声明角色

ASP.NET Core AWS Cognito JWT

具有用户权限的基于 JWT 令牌的授权 Asp.net core 2.0

JWT:如何从声明中的特定键获取值列表。 C# Asp.Net 核心