
Originally Posted by
jrod
How can I set it up in password flow so that only authenticated users in a certain role (i.e., LDAP group) would be granted a token? All other users (whether unauthenticated or unauthorized) would receive an error message.
I will be supporting other flows (auth, client) so whatever solution posed here cannot override other flows.
OK, I think I found the answer. My first attempt extended ResourceOwnerPasswordTokenGranter.getOAuth2Authent ication(), but I abandoned this after realizing that the chain of TokenGranters is associated with the AuthorizationServer. This would have forced me to replace the convenient namespace tag for a custom CompositeTokenGranter chain and replacing the ResourceOwnerPasswordTokenGranter with a custom subclass -- while possible, I felt this was a bit much.
Instead, I noticed the following line one level up the call stack in AbstractTokenGranter.getAccessToken()...
Code:
return tokenServices.createAccessToken(getOAuth2Authentication(outgoingRequest ));
...and chose to override DefaultTokenServices.createAccessToken() to account for the exclusive use case, falling back to the superclass implementation for most normal cases.
Code:
public class CustomTokenServices extends DefaultTokenServices {
private static final GrantedAuthority CUSTOM_AUTHORITY = new SimpleGrantedAuthority("SOME_ROLE");
private static final String CUSTOM_CLIENT_ID = "custom-client";
@Override
public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) throws AuthenticationException {
String clientId = authentication.getAuthorizationRequest().getClientId();
Collection<GrantedAuthority> authorities = authentication.getAuthorities();
if (clientId.equals(CUSTOM_CLIENT_ID) && !authorities.contains(CUSTOM_AUTHORITY))
throw new InvalidGrantException("Could not authorize user: " + authentication.getName());
return super.createAccessToken(authentication);
}
}
But, I wonder now, is this a bad design since I'm delegating authorization failure to the TokenServices rather than handling it in TokenGranter?