Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security OAuth 2: How to get access token and additional data after oauth/token request

I'm securing REST services using Spring Security and Oauth 2.0 authentication protocol.

I've implemented a MVC Spring application and it's working fine. Client requests the Server for an AccessToken by providing client credentials (client_id & client_secret) & user credentials (username & password) calling outh/token service which is defined into servlet-config.xml:

<http pattern="/oauth/token" create-session="stateless"
    authentication-manager-ref="clientAuthenticationManager"
    xmlns="http://www.springframework.org/schema/security" > 
    <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
    <anonymous enabled="false" />
    <http-basic entry-point-ref="clientAuthenticationEntryPoint" />
    <custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" /> 
    <access-denied-handler ref="oauthAccessDeniedHandler" />
 </http>

If credentials are valid, Client will get an Access Token in response like this:

{
    "value": "b663f10d-553d-445b-afde-e9cd84066a1c",
    "expiration": 1406598295994,
    "tokenType": "bearer",
    "refreshToken": {
        "value": "36737abf-24bd-4b86-ad22-601f4d5cdee4",
        "expiration": 1408890295994
    },
    "scope": [],
    "additionalInformation": {},
    "expiresIn": 299999,
    "expired": false
}

I'd like to have a response that also contains user details like this:

{
        "value": "b663f10d-553d-445b-afde-e9cd84066a1c",
        "expiration": 1406598295994,
        "tokenType": "bearer",
        "refreshToken": {
            "value": "36737abf-24bd-4b86-ad22-601f4d5cdee4",
            "expiration": 1408890295994
        },

        "additionalInformation": {},
        "expiresIn": 299999,
        "expired": false,

        "USER_ID": "1",
        "USER_ROLE": "admin",
        "OTHER DATA..."
    }

Does anyone know a way to implement this one?

I've been Googling quite a bit, but I've not found an example implementing a similar scenario. I'm sorry if the question sounds stupid, but I'm very new in Spring Security.

like image 930
Gohan Avatar asked Oct 31 '22 19:10

Gohan


1 Answers

This is how I implemented the similar to your scenario.

1) Create custom token enhancer :

public class CustomTokenEnhancer implements TokenEnhancer {

    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {

        final Map<String, Object> additionalInfo = new HashMap<>();

        User user = (User) authentication.getPrincipal();

        additionalInfo.put("user_id", user.getId());
        additionalInfo.put("business_id", user.getBusinessId());

        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);

        return accessToken;
    }

}

2) User Custom token enhancer in configuration.

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints
        .tokenStore(tokenStore())
        .tokenEnhancer(tokenEnhancerChain())
        .authenticationManager(authenticationManager)
        .accessTokenConverter(jwtAccessTokenConverter());
}

/**
 * Creates a chain of the list of token enhancers.
 * @return
 * 
 * @since 0.0.1
 * 
 * @author Anil Bharadia
 */
public TokenEnhancerChain tokenEnhancerChain() {
    TokenEnhancerChain chain = new TokenEnhancerChain();
    chain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), jwtAccessTokenConverter()));
    return chain;
}

/**
 * Get the new instance of the token enhancer.
 * @return
 */
@Bean
public TokenEnhancer tokenEnhancer() {
    return new CustomTokenEnhancer();
}

That's it. next time you request for the token, you will get it with the additional information.

like image 69
Anil Bharadia Avatar answered Nov 15 '22 07:11

Anil Bharadia