I\'m consuming a set of oAuth2 protected services. It currently works like this: the client logs in using their username and password. I exchange these for a token. I keep the t
I've mashed a similar solution from browsing the Spring Security OAuth sources and bits and pieces of other solutions found online. I'm using Java Config but maybe it can help you map to a xml configuration, here it goes:
@Configuration
@EnableOAuth2Client
public class RestClientConfig {
@Value("${http.client.maxPoolSize}")
private Integer maxPoolSize;
@Value("${oauth2.resourceId}")
private String resourceId;
@Value("${oauth2.clientId}")
private String clientId;
@Value("${oauth2.clientSecret}")
private String clientSecret;
@Value("${oauth2.accessTokenUri}")
private String accessTokenUri;
@Autowired
private OAuth2ClientContext oauth2ClientContext;
@Bean
public ClientHttpRequestFactory httpRequestFactory() {
return new HttpComponentsClientHttpRequestFactory(httpClient());
}
@Bean
public HttpClient httpClient() {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(maxPoolSize);
// This client is for internal connections so only one route is expected
connectionManager.setDefaultMaxPerRoute(maxPoolSize);
return HttpClientBuilder.create().setConnectionManager(connectionManager).build();
}
@Bean
public OAuth2ProtectedResourceDetails oauth2ProtectedResourceDetails() {
ResourceOwnerPasswordResourceDetails details = new ResourceOwnerPasswordResourceDetails();
details.setId(resourceId);
details.setClientId(clientId);
details.setClientSecret(clientSecret);
details.setAccessTokenUri(accessTokenUri);
return details;
}
@Bean
public AccessTokenProvider accessTokenProvider() {
ResourceOwnerPasswordAccessTokenProvider tokenProvider = new ResourceOwnerPasswordAccessTokenProvider();
tokenProvider.setRequestFactory(httpRequestFactory());
return new AccessTokenProviderChain(
Arrays. asList(tokenProvider)
);
}
@Bean
public OAuth2RestTemplate restTemplate() {
OAuth2RestTemplate template = new OAuth2RestTemplate(oauth2ProtectedResourceDetails(), oauth2ClientContext);
template.setRequestFactory(httpRequestFactory());
template.setAccessTokenProvider(accessTokenProvider());
return template;
}
}
One important bit I found is that you need to use the AccessTokenProviderChain even for a single Provider otherwise the automatic token refresh (after authentication) won't work.
To set the user credentials on the first request you'll need this:
@Autowired
private OAuth2RestTemplate restTemplate;
restTemplate.getOAuth2ClientContext().getAccessTokenRequest().set("username", username);
restTemplate.getOAuth2ClientContext().getAccessTokenRequest().set("password", password);
Then you can issue requests as normal using the RestTemplate methods, e.g:
String url = "http://localhost:{port}/api/users/search/findByUsername?username={username}";
ResponseEntity responseEntity = restTemplate.getForEntity(
url, User.class, 8081, username);
If you want to trace the requests on the wire you can set the log level on apache http client to DEBUG, e.g. with Spring Boot:
logging.level.org.apache.http=DEBUG