将JWT声明添加为数组?

时间:2014-12-03 07:57:42

标签: claims-based-identity jwt thinktecture-ident-server

使用thinktecture JWT身份验证资源所有者流程,我使用JWT的声明部分来进行客户端使用。 我的问题是,如果可以在身份服务器中添加声明并将其解码为客户端中的数组。

数组类型没有ClaimTypeValues。

作为解决方法,

 var user = IdentityServerPrincipal.Create(response.UserName, response.UserName);
                user.Identities.First().AddClaims(
                                            new List<Claim>()
                                        {
                                            new Claim(ClaimTypes.Name, response.UserName),
                                            new Claim(ClaimTypes.Email, response.Email),
                                            new Claim(FullName, response.FullName),
                                            new Claim(AuthorizedCompanies,JsonConvert.SerializeObject(response.AuthorizedCompanies))
                                        });
                return new AuthenticateResult(user);

我将声明添加为json数组以声明AuthorizedCompanies并在客户端解析它。如果有的话,这里的设计模式是什么?

4 个答案:

答案 0 :(得分:20)

根据个人经验,当ValueType始终为&#34; String&#34;时,与声明商店互操作更容易。虽然当你知道你正在处理一个复杂的类型时,它看起来似乎是反直觉的,但它至少很容易理解。

我接近这个数组需求的方法是让我的应用程序代码期望对于相关的声明类型存在多个声明,并保持每个声明值的简单类型。< / p>

Examp:

var authorizeCompanies = identity.FindAll(AuthorizedCompanies).Select(c => c.Value);

当然,你也可以这样添加:

identity.AddClaim(ClaimTypes.Name, response.UserName);
identity.AddClaim(AuthorizedCompanies, "CompanyX");
identity.AddClaim(AuthorizedCompanies, "CompanyY");
identity.AddClaim(AuthorizedCompanies, "CompanyZ");

IdentityServer支持此模型。为此类标识生成令牌时,它会自动将该声明的值写为数组。

{
    "aud": "Identity Server example/resources", 
    "iss": "Identity Server example", 
    "exp": 1417718816, 
    "sub": "1234",
    "scope": ["read", "write"], // <-- HERE
    "foo": ["bar", "baz"],      // <-- HERE TOO!
    "nbf": 1417632416
}

这种对权利要求的方法与假设所有权利要求是类型的一对一映射 - &gt;形成对比。值。

答案 1 :(得分:0)

我遇到了类似的问题,就我而言,我声称是数组,但有时只有一项取决于用户权限。在这种情况下,如果使用new Claim(“ key”,“ value”)添加它们,则当存在单个对象时它们将是字符串,而当> 1时将是数组,这将是不可接受的。

在这种情况下,更好的解决方案是使用JwtPayload构建JwtSecurityToken对象。

var state = webapis.avplay.getState();
console.log("[Player][seekBackward] state: ", state);

webapis.avplay.jumpBackward(5000, success =>
{
    console.log("[Player][rewind][success]");
}, error =>
{
    console.error("[Player][seekBackward]", error);
});

这在使用System.IdentityModel.Tokens.Jwt v3.0的.netcore 3.0上有效,但我无法确定其他版本。

答案 2 :(得分:0)

如果要向数组添加 单个值

Identity Server会将值从数组转换为字符串。一个更简单的解决方案是将数组转换为json并添加到valueType为json的声明中。

IList<string> companies = new List<string>();
companies.Add("CompanyA");
string companiesJson = JsonConvert.SerializeObject(companies);
context.IssuedClaims.Add(new Claim("Companies", companiesJson, IdentityServerConstants.ClaimValueTypes.Json));

上述解决方案将允许您添加一个或多个值以声明为数组。

答案 3 :(得分:0)

使用JsonClaimValueTypes作为声明类型

var tokenDescriptor = new SecurityTokenDescriptor
   {
    Subject = new ClaimsIdentity(new Claim[]
     { new Claim("listName", list != null ? JsonSerializer.Serialize(user.RoleName) : string.Empty,JsonClaimValueTypes.JsonArray)
    }}