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.
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.
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.
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.
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.
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:
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.
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?)
Alternatively is there a better approach entirely to such issue?
Thx!
Spring Security OAuth2 project is currently deprecated and Spring Security team has decided to no longer provide support for authorization servers.
The HttpServletRequest.getUserPrincipal() will return the result of SecurityContextHolder.getContext().getAuthentication() . This means it is an Authentication which is typically an instance of UsernamePasswordAuthenticationToken when using username and password based authentication.
Deprecated. See the OAuth 2.0 Migration Guide for Spring Security 5. Rest template that is able to make OAuth2-authenticated REST requests with the credentials of the provided resource.
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.
please check my demo for more details
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.
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/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With