java Spring security oauth2 - 从 OAuth2 主体获取自定义数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16174987/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring security oauth2 - getting custom data from OAuth2 principal
提问by Mark Doyle
I have a site that uses Spring security and has users (username & password) and standard form authentication. I allow users to generate a client Id and client secret linked to their account for use with an OAuth2 secured rest API.
我有一个使用 Spring 安全性并具有用户(用户名和密码)和标准表单身份验证的站点。我允许用户生成链接到他们帐户的客户端 ID 和客户端密码,以便与 OAuth2 安全的休息 API 一起使用。
I use a separate client id & client secret for the API and not username and password so the user can change their password etc without breaking the API credentials, set specific scopes, disable API access etc.
我为 API 使用单独的客户端 ID 和客户端密钥,而不是用户名和密码,因此用户可以更改密码等而不会破坏 API 凭据、设置特定范围、禁用 API 访问等。
I use spring-security-oauth2 (provider) to secure the rest API and I have allowed a client credentials flow. I have setup client authentication for the api so that client id and secret are checked.
我使用 spring-security-oauth2(提供程序)来保护其余 API,并且我允许客户端凭据流。我已经为 api 设置了客户端身份验证,以便检查客户端 ID 和密码。
From a separate application I use the client id and client secret to retreive an access token and start to use it with the api. For the most part I use simple @PreAuthorize expressions typically based on client roles and scope and these appear to work correctly.
从一个单独的应用程序中,我使用客户端 ID 和客户端密码来检索访问令牌并开始将它与 api 一起使用。在大多数情况下,我通常基于客户端角色和范围使用简单的 @PreAuthorize 表达式,这些表达式似乎可以正常工作。
All above appears to work fine
以上所有似乎工作正常
However... I have a few API endpoints now however where I need to implement some more complex rules based on some details from the underlying user - in this case the user that generated the client id and secret.
但是......我现在有一些 API 端点,但是我需要根据底层用户的一些细节来实现一些更复杂的规则 - 在这种情况下是生成客户端 ID 和密码的用户。
As a simple example consider a messaging application where I have an endpoint that allows users to post a new "message" of a specific type that can vary. I have a table of allowed recipients for each user and each type and I want to check that the recipients of the posted message match the allowed recipient for the type. (User allowed recipients data is typically not large, and rarely changes so I'm happy to store a copy of it when generating an access token)
作为一个简单的例子,考虑一个消息传递应用程序,我有一个端点,允许用户发布可以变化的特定类型的新“消息”。我有每个用户和每种类型的允许收件人表,我想检查已发布消息的收件人是否与该类型的允许收件人匹配。(用户允许的收件人数据通常不大,而且很少更改,因此我很乐意在生成访问令牌时存储它的副本)
I get the principal at these endpoints and I see it is an instance of OAuth2Authentication containing:
我在这些端点获得了主体,我看到它是 OAuth2Authentication 的一个实例,其中包含:
- userAuthentication - null - This seems expectable for client credentials flow.
- clientAuthentication is populated and authorizationParameters contains the grant type and client_id
- userAuthentication - null - 这对于客户端凭据流来说似乎是可以预期的。
- 填充了 clientAuthentication 并且 authorizationParameters 包含授权类型和 client_id
I suppose I could use the client id from clientAuthentication.authorizationParameters to lookup the user and the details I require, but that would be a few queries each api call which doesn't seem to make sense.
我想我可以使用 clientAuthentication.authorizationParameters 中的客户端 ID 来查找用户和我需要的详细信息,但这将是每个 api 调用的一些查询,这似乎没有意义。
I would guess there's a nice place/way in Spring OAuth2 libs that while granting the access token that I could add some extra details so that later I could get them from the OAuth2Authentication (principal) object (or something that extends it?)
我猜想在 Spring OAuth2 库中有一个不错的地方/方式,在授予访问令牌的同时,我可以添加一些额外的细节,以便以后我可以从 OAuth2Authentication(主体)对象(或扩展它的东西?)
Alternatively is there a better approach entirely to such issue?
或者,是否有更好的方法完全解决此类问题?
Thx!
谢谢!
采纳答案by achiash
You can override the Token creation class so the token himself would contain the username. (maybe encrypted using the client_secret). This way you can get the user related to a token from the token itself without additional data base access. you should override
您可以覆盖令牌创建类,以便令牌本身包含用户名。(可能使用 client_secret 加密)。通过这种方式,您可以从令牌本身获取与令牌相关的用户,而无需额外的数据库访问。你应该覆盖
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
with your own class, or use TokenEnhancer
与您自己的课程,或使用 TokenEnhancer
回答by Bassem Reda Zohdy
Why you are not using Scopes which can be defined in client details and then use ScopeVoter to validate is this token have proper scope to access this resource or not.
为什么不使用可以在客户端详细信息中定义的范围,然后使用 ScopeVoter 来验证此令牌是否具有访问此资源的适当范围。
please check my demo for more details
请查看我的演示以获取更多详细信息
https://github.com/bassemZohdy/Spring_REST_OAuth_Demo
https://github.com/bassemZohdy/Spring_REST_OAuth_Demo
Update 1: I did not reply to part 2 of your question "getting custom data from OAuth2 principal" you can add rest service on your Authorization server which is be accessed using OAuth token to give you required information about this token user, so you do not have to care about "OAuth2 principal" you are dealing with Authorization server as resource server too.
更新 1:我没有回复您的问题“从 OAuth2 主体获取自定义数据”的第 2 部分,您可以在您的授权服务器上添加休息服务,使用 OAuth 令牌访问该服务以提供有关此令牌用户的所需信息,因此您可以不必关心您将授权服务器也作为资源服务器处理的“OAuth2 主体”。
回答by achiash
In my opinion the right approach here would be to use the oauth2 "password" flow instead of client-credentials. you can create a general client-id and client-secret and give them to all of your users. each user can than request his own token using those client details and his own username and password. This way, each token would be connected to a UserDetails object which will solve your problem. You can see how this done here : https://labs.hybris.com/2012/06/18/trying-out-oauth2-via-curl/
在我看来,正确的方法是使用 oauth2“密码”流而不是客户端凭据。您可以创建一个通用的客户端 ID 和客户端机密并将它们提供给您的所有用户。每个用户都可以使用这些客户端详细信息以及他自己的用户名和密码来请求他自己的令牌。这样,每个令牌都将连接到一个 UserDetails 对象,这将解决您的问题。你可以在这里看到这是如何完成的:https: //labs.hybris.com/2012/06/18/trying-out-oauth2-via-curl/