我正在考虑使用JWT。在jwt.io的示例中,我看到了以下信息:
"admin": true
管理员可以被视为一个角色,因此我有一个问题。在令牌负载中设置角色是一种惯常/良好的做法吗?考虑到角色可以动态修改,我感到有些疑问。
将角色添加到JWT中,如果(a)方便对您很重要,(b)您想避免额外的数据库调用来获取权限,(c)不在意一个人在某些时间窗口内被分配了他不应该拥有的权限,以及(d)您不关心将权限添加到JWT有效负载大小中导致的轻微增加。
将角色添加到JWT并使用黑名单,如果(a)您想防止任何时间窗口内一个人被分配了他不应该拥有的权限,(b)接受这样做的代价是为每个传入请求请求黑名单,并且(c)您不关心将权限添加到JWT有效负载大小中导致的轻微增加。
不要将角色添加到JWT中,并按需获取它们,如果(a)您想防止任何时间窗口内一个人被分配了他不应该拥有的权限,或者(b)避免黑名单的开销,或者(c)避免将JWT有效负载大小略微增加,以及(d)如果您接受这样做的代价是有时/总是在传入请求上查询角色。
如果额外的信息对客户端有用,您可以在令牌中创建声明来存储它们。
但是,我建议只使用 JWT 进行身份验证(确定调用者身份)。如果您需要执行授权操作(确定调用者能做什么),请从您的持久存储中查找调用者的角色/权限以获取最新值。
对于短暂的令牌(例如,在微服务集群中传播身份验证和授权时),将角色包含在令牌中也很有用。
正如这里所提到的,ASP.NET Core将自动检测JWT中提到的任何roles
:
{
"iss": "http://www.jerriepelser.com",
"aud": "blog-readers",
"sub": "123456",
"exp": 1499863217,
"roles": ["Admin", "SuperUser"]
}
并将它们映射到ASP.NET角色中,这通常用于保护应用程序的某些部分。
[Authorize(Roles = "Admin")]
public class SettingsController : Controller
颁发(并签署)JWT的服务器通常被称为授权服务器而不仅仅是身份验证服务器,因此将角色信息(或作用域)包含在JWT中是有意义的,即使它们不是注册声明。
JWT令牌旨在防篡改。
如果JWT令牌包含一个“角色”声明,指示用户具有某个角色或权限,则客户端无法修改该声明以赋予自己额外的权限。
(如果他这样做了)尝试修改令牌可能会被服务器检测到并拒绝,或者可能只会导致客户端被拒绝访问所请求的资源。
例如,在我的情况下,我正在使用API-Platform,它可以通过验证令牌的签名并根据服务器记录验证其内容来检查修改后的令牌。如果检测到任何修改,服务器将拒绝请求,客户端将无法获得所请求的资源的访问权限。