OAuth2是否允许使用非密码或自定义凭据进行授权?

时间:2014-03-25 14:39:55

标签: spring security oauth-2.0 spring-security-oauth2

我正在使用Spring Security OAuth2。客户端应用程序(我们拥有)发出“密码”授权请求,该请求传递用户的用户名和密码。就像草案指定的那样。

我需要这种机制来支持其他类型的凭据,例如卡号,PIN,甚至是预先认证的,不需要密码的授权。

请注意,这些请求只能由特权client_id允许,该特权client_id只能从我们拥有的应用程序中使用。

2 个答案:

答案 0 :(得分:7)

戴夫,谢谢你的快速反应。我实际上找到了一个完美的解决方案,一个你参与的解决方案。它与" custom-grant"令牌者... https://jira.spring.io/browse/SECOAUTH-347

如果我更新了我可能已经知道的相当旧的1.0.0.M5版本。

我的方法是使用支持自定义授权类型的类扩展AbstractTokenGranter(我称之为" studentCard")。一旦身份验证请求到达此处,我就会像ResourceOwnerPasswordTokenGranter一样检查参数列表,而是查找我的自定义" cardNumber"参数。然后,我将自己的基于身份的UsernamePasswordAuthenticationToken版本传递给我的AuthenticationProvider,后者知道如何根据身份证对用户进行身份验证。

以下是我提出的自定义令牌Granter类:

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);
    }
}

我的授权服务器配置:

<!-- 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>

答案 1 :(得分:3)

规范没有明确允许客户端和auth服务器之间直接,非基于密码的用户令牌交换。我认为将密码授权扩展到其他形式的身份验证是很自然的。它符合规范的精神,如果不是这封信的话,那么如果你拥有这种关系的双方,就不会有太多错误。 Spring OAuth并没有明确支持以这种方式扩展密码授权的任何东西,但它并不难做(它实际上只是关于/ token端点的安全性)。我见过的另一种方法是坚持使用密码授予协议,但要使用密码&#34;密码。一次性令牌,客户端只能通过知道用户已经通过其中一种替代方式进行身份验证来获得。