我们是不是应该将授权所需的所有内容存储在 OAuth 令牌中
Posted
技术标签:
【中文标题】我们是不是应该将授权所需的所有内容存储在 OAuth 令牌中【英文标题】:Should we store everything required for Authorization in OAuth token我们是否应该将授权所需的所有内容存储在 OAuth 令牌中 【发布时间】:2017-10-05 15:26:51 【问题描述】:我对 OAuth 令牌有所了解,并在我的上一个项目中使用了它。我们曾经在其中存储角色,以便资源服务器 (WebAPI) 不必请求更多数据来对授权做出任何决定。尽管授权基于权限(根据角色映射)。资源服务器存储了角色和权限的映射关系。
在我当前的项目中,我们计划使用 Azure Active Directory。但是在这个项目中,我们需要存储一个自定义字段,这个字段是所有授权模型的基础(以及角色)。虽然,在 AAD(天蓝色活动目录)中,您可以拥有自定义字段,但这些字段不能以声明的形式发送。 因此,一旦我的资源服务器从客户端应用程序接收到令牌,它就必须为每个用户请求此字段。它显然可以将其存储在缓存中以供进一步请求。但这在我看来并不自然。
我相信,授权所需的所有内容都应该是 OAuth 令牌的一部分。
请分享你的想法。
【问题讨论】:
如果这个字段基本上是资源的一部分,那么你应该把它存储在那里。用户已被识别,因此您可以将(高级)授权保持在资源附近。 感谢 Ruard 的回复。 【参考方案1】:Azure AD 不支持自定义令牌中发出的声明。
但是,作为一种解决方法,您可以在验证令牌后通过在项目中查询 Azure AD Graph 来添加自定义声明。
这是一篇关于 Extending the Azure AD directory schema with custom properties 的有用文章。
【讨论】:
不确定我是否可以编辑签名的令牌,因为它需要传递给另一个服务。 不,它不能编辑签名的令牌。因为这与安全有关。令牌是从 Azure Active Directory 签名的,受 Azure AD 保护的资源每次都会验证签名。【参考方案2】:对于 AAD 并不特别,但是如果您想将所有内容保存在令牌中,那么您肯定必须对令牌进行加密。考虑到您正在加密令牌,我想到了三种方法:
-
简单一,Authz Server用一些私人密码加密token。令牌到达资源服务器后,它将令牌发送到 Authz 服务器进行验证和内容(自省 API 或 OpenID Connect 类 API)
在接下来的两种方法中,Authz Server 加密令牌,RS 在本地解密令牌。
注册资源服务器时,使用资源服务器的公钥进行注册(RS 有公钥和私钥对)。 Authz Server 生成一个随机密码来加密令牌有效负载。随机密码使用资源服务器的公钥加密并添加到 JWT 令牌头中。现在,当令牌到达 RS 时,它首先使用它拥有的私钥解密密码,然后使用该密码(对称密钥加密)解密有效负载。每次都需要生成新密码以确保攻击者每次都能看到新的加密字符串。
与上述类似的方法,在这里,当资源服务器使用它的公钥注册(RS 必须在线)时,Authz 服务器联系 RS 并进行 SSL 握手,它们都交换了一个长期会话密钥实际上可能会持续 1 年或更长时间(取决于您企业的安全限制)。然后,当 authz 服务器生成令牌时,它会使用会话密钥对其进行加密,这一次它不会将会话密钥添加到令牌头中。令牌转到 RS,RS 检查它是否有会话密钥,如果有,它会尝试使用相同的会话密钥解密有效负载。为避免错误,RS 也可以存储 Session key 的有效性。
【讨论】:
以上是关于我们是不是应该将授权所需的所有内容存储在 OAuth 令牌中的主要内容,如果未能解决你的问题,请参考以下文章
我们是否应该将所有必需包及其依赖包放在requirement.txt或仅包含所需的包