Announcement Announcement Module
Collapse
No announcement yet.
granting token in password flow using group-based access Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • granting token in password flow using group-based access

    From all the examples I've seen, it looks like the typical scenario in password flow is to always issue a token to an authenticated user and let subsequent requests to protected resources dictate whether the logged-in user is authorized to access them.

    I have a slightly different use case. 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. For example, a simple solution to my use case would be to change:

    Code:
    <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
    to:

    Code:
    <intercept-url pattern="/oauth/token" access="(my specific role)" />
    But then this would change the access pattern for non-password flows as well, which I don't want.

    Is it possible to have separate <http> blocks pointing to the same URL for different flows?
    Last edited by jrod; Dec 2nd, 2012, 02:34 AM.

  • #2
    Originally posted by jrod View Post
    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?

    Comment


    • #3
      Your token services do not distinguish between grant types, so you don't actually do what you said you wanted to do (only override password grants), although I don't see any reason why it shouldn't add that check. Personally I would prefer to change the TokenGranter. It should be easy to add a <custom-grant/> to the <authorization-server/>.

      Comment

      Working...
      X