复杂的JWT声明

10

JWT RFC似乎没有包含复杂数组的任何问题,例如:

{
    "email": "test@test.com",
    "businesses": [
        {
            "businessId": "1",
            "businessName": "One",
            "roles": [
                  "admin",
                  "accountant"
            ]
        },
        {
            "businessId": "2",
            "businessName": "Two",
            "roles": [
                  "support"
            ]
        }
     ]
}

对于我们的需求来说,这似乎是一个理想的方案,因为作为令牌的一部分,我们希望拥有用户可以访问的企业列表以及他在每个企业中担任的角色(这是其身份的一部分)。 API上的授权策略稍后将理解这些组,并应用所需的授权逻辑。

我注意到,在IdentityServer4中,声明被添加到ProfileDataRequestContextIEnumerable<Claim> IssuedClaims属性中。

是否有推荐的替代这种复杂的声明结构的方法?如果没有,是否有一种方式可以使用IdentityServer4构建该结构(可能是某个扩展?),或者唯一的方式是手动序列化JSON,因为Claim似乎只接受字符串?

PS:我看到了这个问题这个其他问题,其中Identity Server的作者之一谈到了类似的反模式。不确定反模式是拥有复杂的声明结构还是在声明中包含“授权实现细节”。

对此的任何建议都将是极好的!

更新:

经过考虑,我同意拥有复杂的声明层次结构并不理想,我可以通过为每个businessId添加角色前缀来解决这个问题。类似于:

{
    "email": "test@test.com",
    "roles": [
        "1_admin",
        "1_accountant",
        "2_support"
     ],
     "businesses": [
        "1_One",
        "2_Two" 
     ]
}

这样我保持了简单的结构,稍后在客户端或API中,我可以读取声明并发现1是名称为One的业务的ID,并且它具有adminaccount角色。

这会是更好的解决方案吗?

1个回答

16

声明是关于身份信息的,而不是复杂的权限“对象”。你最好使用专用的权限服务,根据用户的身份以任何你想要的格式返回你的权限。

我还希望你的权限数据在令牌被使用时不会发生变化,否则你会得到过期的数据。

话虽如此-在.NET中,声明总是字符串-但你可以通过将 ClaimValueType 设置为 IdentityServerConstants.ClaimValueTypes.Json 来将 JSON 对象序列化到其中。


谢谢。如果索赔(权限数据)发生更改,我想在 API 尝试验证令牌时有一种方法可以使身份验证服务器无效化令牌,以便 API 可以通知客户端(401)需要请求具有更新索赔的新令牌? - diegosasw
另一个选项是,如果客户端想要访问其他业务的资源,则重新发行不同的令牌。在这里使用租户选项是否合适?客户端具有描述其用户身份的令牌,其中包括A、B角色的业务One。用户在UI中切换到业务Two并通过发送tenant=businessTwoId请求新令牌,以便Identity Server看到用户仍然经过身份验证,并发行新令牌,这次包含有关业务Two及其角色的信息。这简化了JWT,不确定是否可能为同一用户和不同租户发行不同的令牌? - diegosasw
3
不要使用令牌来控制权限,这样就不需要围绕它们不应该在那里的事实进行架构设计。 - leastprivilege
1
@leastprivilege,您是否有更多关于为什么我们不应该使用JWT进行授权的信息? - tuler
使用令牌的有效载荷部分。参考链接: https://dev59.com/N4nda4cB1Zd3GeqPEtcE#57197767 - Lovjith
@leastprivilege,您能分享一下如何在每个请求中获取用户的权限吗?我看到您说不要将它们放在JWT中,但似乎没有太多关于它们应该在哪里以及如何处理的信息。 - Seabizkit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接