如何在 JWT 令牌中包含声明?

Posted

技术标签:

【中文标题】如何在 JWT 令牌中包含声明?【英文标题】:How to include claims in JWT token? 【发布时间】:2020-01-23 04:24:15 【问题描述】:

您好,我正在使用 .Net 核心开发 Web 应用程序。我已经实现了 V2 身份验证。现在我需要添加授权。该要求指出,首先,

应用程序的工作不应该是收集 用户,它们应该在用户 JWT 中可用。第二, 应用程序的权限将根据声明授予。

下面是我的验证码。

 services
               .AddAuthentication(o =>
               
                   o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;

               )
               .AddJwtBearer(o =>
               
                   o.Authority = azureActiveDirectoryOptions.Authority;

                   o.TokenValidationParameters = new TokenValidationParameters
                   

                       ValidAudiences = new List<string>
                       
                          azureActiveDirectoryOptions.AppIdUri,
                          azureActiveDirectoryOptions.ClientId
                       ,
                   ;
               );

            services.AddMvc(options =>
            

                var policy = new AuthorizationPolicyBuilder()
                    .RequireAuthenticatedUser()
                    .Build();
                options.Filters.Add(new AuthorizeFilter(policy));
            ).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

有人可以帮我添加基于声明的授权吗?任何帮助将不胜感激。谢谢

【问题讨论】:

阅读此article。 谢谢,但我的问题是对此有什么想法吗? 中间件将帮助将令牌中的声明映射到您的应用程序用户声明,您想在 AAD 颁发的令牌中添加自定义声明吗? 谢谢。是的,我想在 AAD 颁发的令牌中添加自定义声明。我可以知道怎么做吗? 【参考方案1】:

您可以使用以下代码在 JWT 令牌中添加自定义声明。

public string createToken()

    var tokenHandler = new JwtSecurityTokenHandler();

    //create a identity and add claims to the user which we want to log in
    ClaimsIdentity claimsIdentity = new ClaimsIdentity(new[]
    
        new Claim("UserName", "joey"),
        new Claim("Email","xxx@test.com")
    );

    const string sec = "yoursecurityKey";
    var now = DateTime.UtcNow;
    var securityKey = new SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec));
    var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);

    //create the jwt
    var jwtSecurityToken = handler.CreateJwtSecurityToken(
        "issuer",
        "Audience",
        new ClaimsIdentity(claimsIdentity),
        DateTime.Now,
        DateTime.Now.AddHours(1),
        DateTime.Now,
        signingCredentials);
    var tokenString = tokenHandler.WriteToken(token);

    return tokenString;

更多详情可以参考这个article。

更新:

如果是这样,您可以使用JwtBearerEvents 添加声明。

 .AddJwtBearer(o =>
 
     //Additional config snipped
     o.Events = new JwtBearerEvents
     
         OnTokenValidated = async ctx =>
         
             //Get the calling app client id that came from the token produced by Azure AD
             string clientId = ctx.Principal.FindFirstValue("appid");
             var claims = new List<Claim>
             
                 new Claim("UserName", "joey")
             ;
             var appIdentity = new ClaimsIdentity(claims);

             ctx.Principal.AddIdentity(appIdentity);
         
     ;
);

【讨论】:

您好,谢谢。真的我无法理解这段代码,因为我上面的代码已经生成了令牌并且它也正确地进行了身份验证。我想要做的是我想在我的令牌中添加一些声明,并基于我想要验证或授权的声明。谢谢 谢谢。现在我的声明包含新的自定义声明 UserName Joey。只是想了解何时将声明添加到令牌中。在哪个步骤中添加了声明。【参考方案2】:

对于授权部分,您可以add app roles in your application,为用户/组分配角色,以便roles在用户登录并同意后包含在令牌中,您的应用程序可以使用策略来限制基于roles声明的访问。

另一种方法是 use Azure AD Groups and Group Claims 。不同之处在于您的应用程序应检查 groups 声明,

【讨论】:

谢谢 那么 groupMembershipClaims 和 optionalClaims 有什么区别?到目前为止,我所了解的是,基于 azure ad 角色,基于角色的授权将起作用。但是集团声明将如何运作? 将用户分配到不同的组,因此在令牌中有groups 声明显示当前用户是哪些组的成员,然后您可以创建策略并检查声明。groupMembershipClaims 是 aad 的可选声明之一. 那么基于声明的授权与基于组的授权相同吗?声明和基于策略的授权有什么区别? 看来你不明白这个过程。 AAD 颁发的令牌中的声明由 Azure AD 控制,您的应用程序将获取从令牌到应用程序用户声明的声明的映射。如果您想修改 AAD 中的令牌,则接受答案将不起作用,该代码用于在您的应用程序中向用户声明添加声明。这与您的 AAD 令牌声明无关。 @Niranjan 。使用角色或组只会导致在您的应用程序中检查不同的声明(一个是角色,一个是组)。在 .net core 中,您可以使用策略来检查用户声明并使用 [Authorize] 属性来触发授权。

以上是关于如何在 JWT 令牌中包含声明?的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core AWS Cognito JWT

Azure B2C:如何在 JWT 令牌中获得“组”声明

如何使用 JWT Bearer 令牌获取用户声明

如何从 .NET Core 6.0 中的 JWT 安全令牌中读取自定义声明值

如何使用 RestSharp 使用 JWT 访问令牌和用户声明

如何根据用户输入在 Jwt Token 上添加自定义声明?