Skip to content

Instantly share code, notes, and snippets.

@aeisele
Created May 31, 2012 18:53
Show Gist options
  • Save aeisele/2845397 to your computer and use it in GitHub Desktop.
Save aeisele/2845397 to your computer and use it in GitHub Desktop.
use spring security oauth2 resource owner password scheme as authentication provider
public class ResourceOwnerAuthenticationProvider implements AuthenticationProvider {
private String apiEndpoint;
private String clientId;
private String accessTokenUri;
private String clientSecret;
private List<String> scope;
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = (String) authentication.getPrincipal();
String password = (String) authentication.getCredentials();
ResourceOwnerPasswordResourceDetails resourceDetails = createResourceDetails(username, password);
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails);
Client client = new Client(apiEndpoint, restTemplate);
UserData userData = null;
try {
userData = client.selectUser();
} catch (HttpClientErrorException e) {
if (HttpStatus.UNAUTHORIZED.equals(e.getStatusCode())) {
throw new BadCredentialsException("invalid login", e);
}
}
if (userData != null) {
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(
userData.getEmail(),
null,
Arrays.asList(new SimpleGrantedAuthority("ROLE_USER")));
authentication.setDetails(
new AuthenticationContext(
resourceDetails,
restTemplate.getOAuth2ClientContext()));
return authentication;
} else {
throw new IllegalStateException(
"login seems to have been successful but I'm missing the respective user data!");
}
}
private ResourceOwnerPasswordResourceDetails createResourceDetails(String username, String password) {
ResourceOwnerPasswordResourceDetails resourceDetails = new ResourceOwnerPasswordResourceDetails();
resourceDetails.setAccessTokenUri(accessTokenUri);
resourceDetails.setClientId(clientId);
resourceDetails.setClientSecret(clientSecret);
resourceDetails.setScope(scope);
resourceDetails.setUsername(username);
resourceDetails.setPassword(password);
return resourceDetails;
}
public void setAPIEndpoint(String apiEndpoint) {
this.apiEndpoint = apiEndpoint;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public void setAccessTokenUri(String accessTokenUri) {
this.accessTokenUri = accessTokenUri;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public void setScope(List<String> scope) {
this.scope = scope;
}
}
@NZhuravlev
Copy link

NZhuravlev commented Aug 8, 2018

Hey! Thanks for that! What is this Client class?

@nllsdfx
Copy link

nllsdfx commented Jan 30, 2020

Hey! Thanks for that! What is this Client class?

I guess it's something like UserDetailsService or something that does a call to "/userinfo" endpoint. But seems a userData response only contains email as principal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment