Api 在JWT中设置角色是最佳实践吗?

Api 在JWT中设置角色是最佳实践吗?,api,jwt,token,roles,Api,Jwt,Token,Roles,我正在考虑使用JWT。在中,我在有效载荷数据中看到以下信息: "admin": true 管理员可以被视为一个角色,因此我的问题。在令牌负载中设置角色是否是一种习惯/良好做法?考虑到角色可以动态修改,我很有疑问。没有什么可以阻止您创建声明,在您的令牌中存储额外的信息,如果它们对您的客户有用的话 然而,我将仅依赖JWT进行身份验证(调用方是谁)。如果需要执行授权(调用者可以执行的操作),请从持久性存储中查找调用者角色/权限,以获取最新的值 对于短期令牌(例如,在微服务集群中传播身份验证和授权时)

我正在考虑使用JWT。在中,我在有效载荷数据中看到以下信息:

"admin": true

管理员可以被视为一个角色,因此我的问题。在令牌负载中设置角色是否是一种习惯/良好做法?考虑到角色可以动态修改,我很有疑问。

没有什么可以阻止您创建声明,在您的令牌中存储额外的信息,如果它们对您的客户有用的话

然而,我将仅依赖JWT进行身份验证(调用方是谁)。如果需要执行授权(调用者可以执行的操作),请从持久性存储中查找调用者角色/权限,以获取最新的值

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

如上所述,ASP.NET Core将自动检测JWT中提到的任何
角色

{
  "iss": "http://www.jerriepelser.com",
  "aud": "blog-readers",
  "sub": "123456",
  "exp": 1499863217,
  "roles": ["Admin", "SuperUser"]
}
并将它们“映射”到通常用于保护应用程序某些部分的对象

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

发出(并签署)JWT的服务器通常被称为身份验证服务器,而不仅仅是身份验证服务器,因此在JWT中包含角色信息(或范围)是有意义的,即使它们不是。

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

什么时候应该使用JSON Web令牌? 授权:这是使用JWT最常见的场景。一旦用户登录,每个后续请求将包括JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是目前广泛使用JWT的一种功能,因为它的开销小,并且能够轻松地跨不同的域使用

也就是说,从安全的角度来看,您应该仔细考虑是否真的要在令牌中包含角色或权限

(下文可以理解为对保留较短的公认答案的更“深入”的后续行动)

创建并签署令牌后,您将授予该权限,直到令牌过期。但是如果您意外地授予了管理员权限呢?在令牌过期之前,现在有人正在您的站点上使用错误分配的权限进行操作

有些人可能会认为代币是短暂的,但鉴于一个人在短时间内可能造成的伤害,这不是一个有力的论点。还有一些人主张为令牌维护单独的黑名单数据库表,这解决了令牌无效的问题,但在后端添加了某种会话状态跟踪,因为您现在需要跟踪当前存在的所有会话,所以您必须在每次请求到达时对黑名单进行db调用,以确保它尚未被列入黑名单。有人可能会说,这首先违背了“将角色放入JWT以避免额外的db调用”的目的,因为您只是将额外的“角色db调用”换成了额外的“黑名单db调用”

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

顺便说一句,如果您查看了这些声明的列表,您将看到这些声明是围绕身份验证而发展的,而不是针对允许用户执行的操作(授权)

总之,你可以

  • 在JWT中添加角色如果(a)便利性对您很重要,并且(b)您希望避免额外的数据库调用以获取权限,并且(c)不关心分配给某人不应该拥有的权限的小时间窗口,以及(d)您不关心(轻微)由于添加权限,JWT的有效负载大小增加

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

  • 如果(a)您希望防止任何时间窗口中的人被分配了他不应该拥有的权利,或者(b)避免黑名单的开销,或者(c)避免增加JWT有效负载的大小以略微增加和(d),则不要向JWT添加角色并按需获取角色如果您接受这是以有时/总是查询传入请求上的角色为代价的


缺点是应用程序必须知道这些信息。在许多环境中,除了令牌中的声明外,应用程序无法访问有关用户的其他信息。因此,这取决于具体的用例。但是,是的,在JWT中添加角色信息是完全正常的,因为身份验证和授权这两个词是相同的,可以互换使用。感谢您提供的信息:)身份验证基本上是确保用户是他们所说的人的实践,授权是确保用户有权访问目的地的过程。OIDC和中央标识系统等现代标准利用JWT声明,实现对访问的完全中央控制。然后,系统只需要映射到声明。OIDC中的令牌也可用于生成特定于应用程序的令牌。当然,您仍然需要以某种方式将它们放入其中;-)这个问题似乎是实现这一点的一种流行方式——特别是当您在.NET领域,需要创建具有ASPNET角色或角色声明的令牌时。更不用说令牌是作为