首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JwtToken - claim JwtTokenTypes.Subject解析为ClaimTypes.NameIdentifier,这是为什么?如何防止?

JwtToken - claim JwtTokenTypes.Subject解析为ClaimTypes.NameIdentifier,这是为什么?如何防止?
EN

Stack Overflow用户
提问于 2016-08-25 17:19:59
回答 1查看 4.2K关注 0票数 2

我创建了这样的JwtToken:

代码语言:javascript
复制
        X509Certificate2 cert = certificateStore.Certificate;

        var now = DateTime.UtcNow;
        var tokenHandler = new JwtSecurityTokenHandler();
        var tokenDescriptor = new SecurityTokenDescriptor()
        {
            Subject = new ClaimsIdentity(new[]
            {
                    new Claim(JwtClaimTypes.Subject, upn),
                    new Claim(REQUEST_TYPE_NAME, requestType),
                    new Claim(DOMAIN_NAME, domain),
                }),
            Lifetime = new Lifetime(now, now.AddMinutes(60)),
            SigningCredentials = new X509SigningCredentials(cert),
            TokenIssuerName = ISSUER
        };

        SecurityToken token = tokenHandler.CreateToken(tokenDescriptor);

这是正确的。创建令牌并将其第一个声明命名为"sub“,这是JwtTokenTypes.Subject的内容。我通过jwt web查过了。

问题是,我有这个解决索赔的方法:

代码语言:javascript
复制
        if (string.IsNullOrWhiteSpace(token)) throw new MissingTokenException("Token should not be null.");

        var tokenHandler = new JwtSecurityTokenHandler();
        var securityToken = new X509SecurityToken(new X509Certificate2(new X509RawDataKeyIdentifierClause(certificateStore.Certificate).GetX509RawData()));
        var validationParameters = new TokenValidationParameters()
        {
            IssuerSigningToken = securityToken,
            ValidateAudience = false,
            ValidateActor = false,
            ValidIssuer = ISSUER
        };

        SecurityToken securedToken = new JwtSecurityToken();
        ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(token, validationParameters, out securedToken);

        Claim claim = claimsPrincipal.FindFirst(m => string.Equals(m.Type, REQUEST_TYPE_NAME, StringComparison.OrdinalIgnoreCase));
        if (claim != null && !string.Equals(claim.Value, requestType, StringComparison.OrdinalIgnoreCase))
        {
            throw new MismatchedTokenException("Token is not of the proper type.");
        }

        upn = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(JwtClaimTypes.Subject) || m.Type.Equals(ClaimTypes.NameIdentifier))?.Value;

        domain = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(DOMAIN_NAME))?.Value;

在方法的末尾,您可以看到我检查了JwtClaimTypes.Subject和ClaimTypes.NameIdentifiew的索赔名称,前者应该是,后者实际是。

你知道为什么会发生这种转换吗?或者如何防止它们?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-25 19:16:08

在此之前,您需要添加:

代码语言:javascript
复制
JwtSecurityTokenHandler.InboundClaimTypeMap.Clear();

这清除了jwt声明的映射。

完成映射是为了使jwt声明适应.net类型的声明。如果您要避免映射,则需要设置name和role的声明类型(如果您想从标识(IPrincipal.IsInRole或Identity.Name)中使用它们)。

您可以在创建ClaimsIdentity时执行此操作:

代码语言:javascript
复制
    Subject = new ClaimsIdentity(new[]
    {
            new Claim(JwtClaimTypes.Subject, upn),
            new Claim(REQUEST_TYPE_NAME, requestType),
            new Claim(DOMAIN_NAME, domain),
        }, "<auth type>", "name", "role"),

您必须将authType更改为类似cookie的名称,名称和角色声明名称很可能是这样的。

另一种方法是在令牌验证参数上设置它:

代码语言:javascript
复制
var validationParameters = new TokenValidationParameters()
    {
        IssuerSigningToken = securityToken,
        ValidateAudience = false,
        ValidateActor = false,
        ValidIssuer = ISSUER,
        NameClaimType = "name",
        RoleClaimType = "role"
    };
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39141310

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档