Microsoft.IdentityModel.Tokens:添加其他声明

Posted

技术标签:

【中文标题】Microsoft.IdentityModel.Tokens:添加其他声明【英文标题】:Microsoft.IdentityModel.Tokens: Add additonal claims 【发布时间】:2017-12-14 17:59:34 【问题描述】:

背景

出于 authn/z 的目的,我们使用 JOSE-JWT 创建 JWT 令牌。此令牌通过 Authorize: Bearer HTTP 标头传递到不同的微服务以模拟调用者。

微服务本身利用 Microsoft.IdentityModel.Tokens 来验证 JWT 令牌:

using System;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using Microsoft.AspNetCore.Builder;

// The key length needs to be of sufficient length, or otherwise an error will occur.
var tokenSecretKey = Encoding.UTF8.GetBytes(Configuration["TokenSecretKey"]);

var tokenValidationParameters = new TokenValidationParameters

    // Token signature will be verified using a private key.
    ValidateIssuerSigningKey = true,
    RequireSignedTokens = true,
    IssuerSigningKey = new SymmetricSecurityKey(tokenSecretKey),

    // Token will only be valid if contains "accelist.com" for "iss" claim.
    ValidateIssuer = true,
    ValidIssuer = "accelist.com",

    // Token will only be valid if contains "accelist.com" for "aud" claim.
    ValidateAudience = true,
    ValidAudience = "accelist.com",

    // Token will only be valid if not expired yet, with 5 minutes clock skew.
    ValidateLifetime = true,
    RequireExpirationTime = true,
    ClockSkew = new TimeSpan(0, 5, 0),

    ValidateActor = false,
;

app.UseJwtBearerAuthentication(new JwtBearerOptions

    AutomaticAuthenticate = true,
    TokenValidationParameters = tokenValidationParameters,
);

某些 JWT 保留声明将自动填充到 HttpContext.User 中,即


问题

是否有一种简单而优雅的方法可以将其他自定义声明填充到 HttpContext.User 中?目前我能想到的唯一方法是解码令牌并调用 HttpContext.User.Claims.Add(...)

提前谢谢你!

【问题讨论】:

嗨@Fabe,您是否尝试过我下面回答中的方法? 【参考方案1】:

您无需解码令牌并添加您的custom claims,而是即时执行Unionusercustom 声明,如下所示:

private async Task<JwtSecurityToken> GetJwtSecurityToken(ApplicationUser user)
        
            //Get the user claims
            var userClaims = await _userManager.GetClaimsAsync(user);
            //Merge the claims here
            return new JwtSecurityToken(
                issuer: "", //Insert your issuer
                audience: "",//Insert your audience
                claims: GetTokenClaims(user).Union(userClaims), //This is the Union you need
                expires: DateTime.UtcNow.AddMinutes(5),//Add expiry time here
                signingCredentials: new SigningCredentials(IssuerSigningKey, SecurityAlgorithms.HmacSha256)//Do your magic here
            );
        

GetTokenClaims() 方法只会返回一个自定义声明列表,例如:

private static IEnumerable<Claim> GetTokenClaims(ApplicationUser user)

    return new List<Claim>
        
        new Claim("UserName", user.UserName),
        new Claim("Email", user.Email),
        new Claim("FirstName", user.FirstName),
        new Claim("LastName", user.LastName),
        new Claim("Phone", user.PhoneNumber),
        //More custom claims
        ;

最后,你可以把它总结如下:

//Get the token combination
var token = await GetJwtSecurityToken(user);
//Write and return the token
return Ok(new

    token = new JwtSecurityTokenHandler().WriteToken(token),
    expiration = token.ValidTo,              
);

【讨论】:

非常感谢您的帮助!这不完全是我的意思。您正在描述如何向现有令牌添加其他声明。我已经将现有声明添加到 JWT 令牌。当客户端收到令牌时,一些 JWT 声明会自动填充到 HttpContext.User 中,但是当我尝试访问其他 JWT 声明时,会返回 null。很抱歉没有这么清楚。我会更新我的问题。

以上是关于Microsoft.IdentityModel.Tokens:添加其他声明的主要内容,如果未能解决你的问题,请参考以下文章