在JWT中更新/更改角色声明(或任何其他声明)

时间:2017-05-15 11:13:22

标签: authentication oauth asp.net-core jwt asp.net-core-webapi

我将用户角色存储在JWT中(以限制API端点)。管理员可以更改角色。

如果角色发生变化。我怎么能在所有代币中反映这一点?我考虑过几个解决方案:

  • 如果我使用刷新令牌,则用户必须等到访问令牌的到期日期过期。

  • 我可以记录已更改的用户ID并检查每个请求,然后在用户更改后返回新令牌。

有没有一种标准方法可以做到这一点?

5 个答案:

答案 0 :(得分:8)

JWT令牌是不可变的,因此您无法更改/更新现有令牌的声明 - 因此您必须发出新的JWT令牌。

这导致了JWT的最大问题 - 令牌撤销。没有好的解决方案。你能做的是

  • 保持JWT到期日期短(并可选择使用刷新令牌)

  • 使用黑名单保留已撤销令牌的列表(当然会以这种方式丢失'无状态'部分)

  • 更改密钥(请记住,这会撤消所有用户的所有有效令牌)

最佳解决方案取决于具体案例。

答案 1 :(得分:6)

如果您关心即时更改,刷新令牌似乎不是解决方案,如果您撤销其权限,您可能不希望用户访问审核工具一段时间。< / p>

你可以做的是在jwt令牌中保留一个相对于用户的版本号,就像mongoose对它的versionKey一样。通过这样做,您将能够针对给定用户的数据库中的版本检查此版本。每次更改此用户的角色时,如果jwt的版本不匹配,您将增加此版本,只需重新创建具有正确角色和版本的新版本,然后将其发送回用户。

我不相信这有一个合适的标准,因为jwt在设计上是不可变的,如果你需要更新&#34;你必须完全改变它。它

答案 2 :(得分:0)

要解决这种情况,您可以缩短令牌的寿命,一旦令牌过期,您可以在进行隐式授予的情况下静默续订令牌,或者使用刷新令牌机制从授权服务器发行新令牌。角色更改后,它可能不会立即反映在令牌中,但是在令牌更新后将可用。

答案 3 :(得分:0)

@Janar说,三种解决方案可以处理不同的情况,但是它们仍然存在相应的缺点。

我还想撤销您的令牌:

  1. iat设置为JWT有效负载。 (您应该知道什么是iat
  2. 吊销用户的令牌:
    • 找到用户ID
    • 让auth服务器拒绝当前时间之前的令牌(由iat判断)并属于该用户(由userId判断)

答案 4 :(得分:-1)

对此的解决方案是在使用 JWT 令牌时将身份验证和授权分开。使用令牌进行身份验证(声明 ID)并使用该 ID 检查数据库中的授权。考虑到您现在必须检查每个请求的授权,这可能会增加每个请求的延迟。但是,这可以通过使用内存数据结构存储(例如 Redis)作为缓存来缓解。在每次权限更改时,删除缓存并再次调用权限。