在 JWT 中设置 Roles 是最佳实践吗?

Is setting Roles in JWT a best practice?

我正在考虑使用 JWT。在 jwt.io example 中,我在有效负载数据中看到以下信息:

"admin": true

管理员可以被视为一个角色,因此我的问题。在令牌负载中设置角色是一种 habitual/good 做法吗?鉴于角色可以动态修改,我很疑惑

没有什么能阻止您创建声明以在您的令牌中存储额外信息,前提是它们对您的客户有用。

但是我只会依赖 JWT 进行 身份验证(调用者是谁)。如果您需要执行 授权(调用者可以做什么),请从您的持久存储中查找调用者 roles/permissions 以获得最新的值。

对于短期令牌(例如,在微服务集群中传播身份验证和授权时),我发现在令牌中包含角色很有用。

如前所述here,ASP.NET核心会自动检测JWT中提到的任何roles

{
  "iss": "http://www.jerriepelser.com",
  "aud": "blog-readers",
  "sub": "123456",
  "exp": 1499863217,
  "roles": ["Admin", "SuperUser"]
}

和 'map' 它们到 ASP.NET Roles 它们通常用于保护应用程序的某些部分。

[Authorize(Roles = "Admin")]
public class SettingsController : Controller

发出(并签署)JWT 的服务器通常称为 authorization server and not just an authentication server, so it makes sense to include role information (or scope) in the JWT, even though they're not registered claims

官方 JWT 站点明确mentions“授权”(与“身份验证”相反)作为 JWT 的用例:

When should you use JSON Web Tokens? Authorization: This is the most common scenario for using JWT. Once the user is logged in, each subsequent request will include the JWT, allowing the user to access routes, services, and resources that are permitted with that token. Single Sign On is a feature that widely uses JWT nowadays, because of its small overhead and its ability to be easily used across different domains.

也就是说,从安全的角度来看,您应该三思而后行,是否真的想在令牌中包含角色或权限。

(下面的文字可以理解为对相当简短的已接受答案的更“深入”跟进)

创建并签署令牌后,您将授予权限,直到令牌过期。但是,如果您不小心授予了管理员权限怎么办?在令牌过期之前,有人正在使用错误分配的权限在您的网站上运行。

有些人可能会争辩说令牌是短暂的,但考虑到一个人可以在短时间内造成的伤害量,这不是一个强有力的论据。其他一些人主张为令牌维护一个单独的黑名单数据库table,这解决了使令牌无效的问题,但是在后端添加了某种会话状态跟踪,因为您现在需要跟踪所有当前会话在那里——所以你必须在每次请求到达时对黑名单进行数据库调用,以确保它还没有被列入黑名单。有人可能会争辩说,这首先违背了“将角色放入 JWT 以避免额外的数据库调用”的目的,因为您只是用额外的“角色数据库调用”换取额外的“黑名单数据库调用” .

因此,您可以将有关用户角色和权限的信息保存在您的身份验证服务器的数据库中,而不是向令牌添加授权声明,您可以随时完全控制这些信息(例如,撤销用户的特定权限) .如果请求到达,您从授权服务器(或您存储权限的任何地方)获取当前角色。

顺便说一句,如果您查看 public claims registered by the IANA 的列表,您会发现这些声明围绕身份验证展开,而不是处理允许用户执行的操作(授权)。

总之,您可以...

  • 向您的 JWT 添加角色 如果 (a) 方便对您很重要并且 (b) 您希望避免额外的数据库调用来获取权限并且 ( c) 不关心小时间 windows 一个人被分配了他不应该拥有的权利,并且 (d) 你不关心由于添加权限而导致的 JWT 有效负载大小的(轻微)增加。

  • 向您的 JWT 添加角色并使用黑名单 如果 (a) 您想要阻止任何时间 windows 某人有权分配他不应该拥有并且(b)接受这是以为每个传入请求向黑名单发出请求为代价的,并且(c)您不关心由于添加而导致的 JWT 有效负载大小的(轻微)增加权限。

  • 不向您的 JWT 添加角色并按需获取它们 如果 (a) 您想要阻止任何时间 windows分配了他不应该拥有的权利,或者 (b) 避免黑名单的开销,或者 (c) 避免增加 JWT 有效负载的大小以略微增加,并且 (d) 如果您接受这是以 [=51 为代价的=] 查询传入请求的角色。