无法访问 WebApi 授权令牌中的 JWT 声明

Posted

技术标签:

【中文标题】无法访问 WebApi 授权令牌中的 JWT 声明【英文标题】:Cannot access JWT claim in WebApi authorization token 【发布时间】:2019-04-17 04:39:11 【问题描述】:

我能够在我的 MVC WebApi 中实现以下 JWT 解决方案,如下链接 JWT Authentication for Asp.Net Web Api

现在,我想访问控制器中的声明,但所有声明都为空。我已经尝试了一些东西,它们都返回 null。

JwtAuthenticationAttribute 中如何添加声明:

protected Task<IPrincipal> AuthenticateJwtToken(string token)
        
            string username;

            if (ValidateToken(token, out username))
            
                //Getting user department to add to claim.
                eTaskEntities _db = new eTaskEntities();
                var _user = (from u in _db.tblUsers join d in _db.tblDepartments on u.DepartmentID equals d.DepartmentID select u).FirstOrDefault();
                var department = _user.DepartmentID;

                // based on username to get more information from database in order to build local identity
                var claims = new List<Claim>
                
                    new Claim(ClaimTypes.Name, username),
                    new Claim(ClaimTypes.SerialNumber, department.ToString())
                    // Add more claims if needed: Roles, ...
                ;

                var identity = new ClaimsIdentity(claims, "Jwt");
                IPrincipal user = new ClaimsPrincipal(identity);

                return Task.FromResult(user);
            

            return Task.FromResult<IPrincipal>(null);
        

到目前为止我已经尝试过什么

获取声明的扩展方法:

public static class IPrincipleExtension

    public static String GetDepartment(this IIdentity principal)
    
        var identity = HttpContext.Current.User.Identity as ClaimsIdentity;
        if (identity != null)
        
            return identity.FindFirst("SerialNumber").Value;
        
        else
            return null;
    

使用帖子中定义的函数(上面的链接):

TokenManager.GetPrincipal(Request.Headers.Authorization.Parameter).FindFirst("SerialNumber")

尝试通过线程访问Claim:

((ClaimsPrincipal)System.Threading.Thread.CurrentPrincipal.Identity).FindFirst("SerialNumber")

对于上述所有情况,声明始终为空。我做错了什么?

【问题讨论】:

在您的GetDepartment 方法中,如果您将手表添加到identity 变量并检查identity.Claims,您会看到什么? 【参考方案1】:

您应该尝试这样做以获得您的声明:

if (HttpContext.User.Identity is System.Security.Claims.ClaimsIdentity identity)
                   
    var serialNum = identity.FindFirst(System.Security.Claims.ClaimTypes.SerialNumber).Value;


我保留identity.FindFirst("string_here").Value 以供我这样设置声明时使用:

var usersClaims = new[]
               
    new Claim("string_here", "value_of_string", ClaimValueTypes.String),
    ...
;

而不是像这样使用“预建”值:

var usersClaims = new[]
               
    new Claim(ClaimTypes.Name, "value_of_name", ClaimValueTypes.String),
    ...
;

【讨论】:

以上是关于无法访问 WebApi 授权令牌中的 JWT 声明的主要内容,如果未能解决你的问题,请参考以下文章

如何生成包含一些自定义声明的 JWT 访问令牌?

.NET 5 Web API 中的 JWT 授权和刷新令牌

Web API 中的多个 JWT 授权令牌

如何让我的 Auth0 权限进入 AWS HTTP API Jwt 授权方的访问令牌的范围声明?

在 .net 核心 web api 中存储 JWT 令牌的位置?

WebApi 2始终使用自定义JWT令牌返回401授权