Search code examples
javaspringoauth-2.0tokenspring-security-oauth2

OAuth2Client return the same token every time


I have the AuthorizationServer. Besides standard functions i have controller who let to create user. After successful user creates the method must to return token for this user. The problem is that the method return valid token only at first call. At next calls - following users will get the first user's token. I tried to set scope(request) for restTemplate - but obtained the error: " Scope 'request' is not active for the current thread"

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {  

    @Override
    public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
      ...
    }
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
     ...
    }

    protected ResourceOwnerPasswordResourceDetails getOwnerPasswordResource(){
        ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
        List scopes = new ArrayList<String>(3);
        scopes.add(SCOPE_READ);
        scopes.add(SCOPE_WRITE);
        scopes.add(SCOPE_TRUST);
        resource.setAccessTokenUri(tokenUrl);
        resource.setClientId(CLIENT_ID);
        resource.setClientSecret(CLIENT_SECRET_UNCODED);
        resource.setGrantType(GRANT_TYPE_PASSWORD);
        resource.setScope(scopes);
        return resource;
    }
}

Here the OAuth2Client:

@EnableOAuth2Client
@Configuration
public class ClientConfig {
    @Autowired
    AuthorizationServerConfig authorizationServerConfig;

    @Bean
    //@Scope("request")
    public OAuth2RestOperations restTemplate() {
        AccessTokenRequest atr = new DefaultAccessTokenRequest();

        return new OAuth2RestTemplate(authorizationServerConfig.getOwnerPasswordResource(), new DefaultOAuth2ClientContext(atr));
    }

}

And my controller:

@RestController
public class UserRestController {
    @Autowired
    private OAuth2RestOperations restTemplate;

    @PostMapping("/user")
    public OAuth2AccessToken createUserCredential(@RequestBody UserCredential user) {
        user.validate();
        userCredentialService.checkAndSaveUser(user, getClientIp(request));

        restTemplate.getOAuth2ClientContext().getAccessTokenRequest().set("username", user.getLogin());
        restTemplate.getOAuth2ClientContext().getAccessTokenRequest().set("password", user.getPassword);
        return restTemplate.getAccessToken();
    }
}

May be exists more correct way to obtain token inside of AuthorizationServer ?


Solution

  • I thought have some special way.. but not found it. And solved problem on following way

     @EnableOAuth2Client
    @Configuration
    public class OAuthClientConfig {
    
        @Autowired
        AuthorizationServerConfig authorizationServerConfig;
    
        public OAuth2RestOperations restTemplate() {
            AccessTokenRequest atr = new DefaultAccessTokenRequest();
    
            return new OAuth2RestTemplate(authorizationServerConfig.getOwnerPasswordResource(), new DefaultOAuth2ClientContext(atr));
        }
    }
    

    And my controller:

    @RestController
    public class UserRestController {
    
        @Autowired
        private OAuthClientConfig oAuthClientConfig;
    
        @PostMapping("/user")
        public OAuth2AccessToken createUserCredential(@RequestBody UserCredential user) {
            user.validate();
            userCredentialService.checkAndSaveUser(user, getClientIp(request));
    
            OAuth2RestOperations restTemplate = oAuthClientConfig.restTemplate();
            restTemplate.getOAuth2ClientContext().getAccessTokenRequest().set("username", user.getLogin());
            restTemplate.getOAuth2ClientContext().getAccessTokenRequest().set("password", user.getPassword);
            return restTemplate.getAccessToken();
        }
    }
    

    May be it will help to someone