我有一个使用Spring安全性的网站,并拥有用户(用户名和密码)和标准表单身份验证。我允许用户生成链接到其帐户的客户端ID和客户端密码,以便与OAuth2安全的rest API一起使用。
我使用单独的客户端ID& API的客户机密,而不是用户名和密码,因此用户可以在不破坏API凭据,设置特定范围,禁用API访问等的情况下更改密码等。
我使用spring-security-oauth2(提供程序)来保护其余的API,并且我已经允许客户端凭据流。我已经为api设置了客户端身份验证,以便检查客户端ID和密码。
从单独的应用程序中,我使用客户端ID和客户端密钥来检索访问令牌并开始将其与api一起使用。在大多数情况下,我使用简单的@PreAuthorize表达式,通常基于客户端角色和范围,这些表达似乎可以正常工作。
以上所有内容似乎都可以正常使用
然而......我现在有一些API端点,但是我需要根据底层用户的一些细节来实现一些更复杂的规则 - 在这种情况下是生成客户端ID和密码的用户。
作为一个简单的示例,考虑一个消息传递应用程序,其中我有一个端点,允许用户发布可能变化的特定类型的新“消息”。我有一个允许每个用户和每种类型的收件人表,我想检查发布邮件的收件人是否与该类型的允许收件人匹配。 (用户允许的收件人数据通常不大,很少更改,所以我很乐意在生成访问令牌时存储它的副本)
我在这些端点获得了主体,我发现它是OAuth2Authentication的一个实例,包含:
我想我可以使用来自clientAuthentication.authorizationParameters的客户端ID来查找用户和我需要的详细信息,但是每个api调用会有一些查询似乎没有用。
我猜在Spring OAuth2库中有一个不错的地方/方式,在授予访问令牌时我可以添加一些额外的细节,以便以后我可以从OAuth2Authentication(主体)对象中获取它们(或者扩展它的东西? )
或者,对这样的问题有更好的方法吗?
THX!
答案 0 :(得分:6)
为什么您没有使用可在客户端详细信息中定义的Scope,然后使用ScopeVoter来验证此令牌是否具有访问此资源的适当范围。
请查看我的演示了解更多详情
https://github.com/bassemZohdy/Spring_REST_OAuth_Demo
更新1: 我没有回复您的问题的第2部分“从OAuth2主体获取自定义数据”您可以在授权服务器上添加休息服务,该服务可以使用OAuth令牌访问,以便为您提供有关此令牌用户的必需信息,因此您不必关心“OAuth2 principal”你也在处理授权服务器作为资源服务器。
答案 1 :(得分:5)
在我看来,这里的正确方法是使用oauth2“密码”流而不是客户端凭证。您可以创建一般客户端ID和客户端密钥,并将其提供给您的所有用户。每个用户都可以使用这些客户端详细信息和他自己的用户名和密码来请求自己的令牌。 这样,每个令牌都将连接到UserDetails对象,这将解决您的问题。 您可以在此处查看此操作:https://labs.hybris.com/2012/06/18/trying-out-oauth2-via-curl/
答案 2 :(得分:5)
您可以覆盖令牌创建类,以便令牌本身包含用户名。 (可能使用client_secret加密)。 这样,您可以从令牌本身获取与令牌相关的用户,而无需额外的数据库访问。 你应该覆盖
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
使用您自己的课程,或使用TokenEnhancer