I'm using Spring Security OAuth2. The client application (that we own) makes a "password" grant request that passes the user's username and password. Just like the draft specifies.
I need this mechanism to also support other types of credentials, like card number, PIN, and even a pre-authenticated, password not required grant.
Please keep in mind, these requests will only be permitted by a privileged client_id, one that will only be used from the application we own.
Dave, thanks for the quick response. I actually found the perfect solution, one which you took part in. It has to do with "custom-grant" token granters... https://jira.spring.io/browse/SECOAUTH-347
Had I updated my rather old 1.0.0.M5 version I might have known about those.
My approach was to extend AbstractTokenGranter with a class that supports a custom grant type (I call it "studentCard"). Once an authentication request makes it here, I examine the parameter list just like ResourceOwnerPasswordTokenGranter, but instead look for my custom "cardNumber" parameter. I then pass my own, id-based version of UsernamePasswordAuthenticationToken to my AuthenticationProvider, which knows how to authenticate users based on id card.
Here is the custom token granter class I came up with:
public class StudentCardTokenGranter extends AbstractTokenGranter {
    private static final String         GRANT_TYPE = "studentCard";
    private final AuthenticationManager authenticationManager;
    public StudentCardTokenGranter(AuthenticationManager authenticationManager,
        AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService) {
    super(tokenServices, clientDetailsService, GRANT_TYPE);
    this.authenticationManager = authenticationManager;
    }
    @Override
    protected OAuth2Authentication getOAuth2Authentication(AuthorizationRequest clientToken) {
    Map<String, String> parameters = clientToken.getAuthorizationParameters();
    String cardNumber = parameters.get("cardNumber");
    Authentication userAuth = new StudentCardAuthenticationToken(cardNumber);
    try {
        userAuth = authenticationManager.authenticate(userAuth);
    } catch (BadCredentialsException e) {
        // If the username/password are wrong the spec says we should send 400/bad grant
        throw new InvalidGrantException(e.getMessage());
    }
    if (userAuth == null || !userAuth.isAuthenticated()) {
        throw new InvalidGrantException("Could not authenticate student: " + cardNumber);
    }
    return new OAuth2Authentication(clientToken, userAuth);
    }
}
And my authorization server config:
<!-- Issues tokens for both client and client/user authorization requests -->
<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices">
    <oauth:refresh-token />
    <oauth:client-credentials />
    <oauth:password authentication-manager-ref="myUserManager" />
    <oauth:custom-grant token-granter-ref="studentCardGranter" />
</oauth:authorization-server>
<bean id="studentCardGranter" class="com.api.security.StudentCardTokenGranter">
    <constructor-arg name="authenticationManager" ref="myUserManager" />
    <constructor-arg name="tokenServices" ref="tokenServices" />
    <constructor-arg name="clientDetailsService" ref="clientDetails" />
</bean>
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With