2014-03-25 57 views
6

我使用Spring Security OAuth2。客戶端應用程序(我們擁有的)發出一個「密碼」授予請求,以傳遞用戶的用戶名和密碼。就像草案所規定的一樣。OAuth2是否允許使用非密碼或自定義憑證進行授權?

我需要這種機制來支持其他類型的憑證,如卡號,PIN碼,甚至是預先認證的密碼不需要授權。

請注意,這些請求只能通過特權client_id來獲得,該特權只能從我們擁有的應用程序中使用。

回答

5

Dave,感謝您的快速響應。我居然找到了完美的解決方案,其中一個你的一部分。它與「定製批」令牌granters做... https://jira.spring.io/browse/SECOAUTH-347

如果我更新了我的很舊1.0.0.M5版本我早就知道關於那些。

我的方法是擴展AbstractTokenGranter一個支持自定義授權類型的類(我稱之爲「studentCard」)。一旦身份驗證請求將其發送到此處,我將檢查參數列表,如ResourceOwnerPasswordTokenGranter,但請查找我的自定義「cardNumber」參數。然後,我將我自己的,基於id的版本UsernamePasswordAuthenticationToken傳遞給我的AuthenticationProvider,該AuthenticationProvider知道如何基於身份證對用戶進行身份驗證。

這裏是我想出了一個自定義的令牌授予者類:

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> 
+0

我也在尋找類似的東西。但'AbstractTokenGranter'在其構造函數中有4個參數,所以'super'調用在上例中顯示編譯錯誤。 –

+1

我在這裏找到了解決方案,用於我的查詢。 http://stackoverflow.com/questions/25264358/spring-security-oauth2-with-custom-tokengranter-in-version-2-0/25270572#25270572 –

2

該規範沒有明確允許直接在客戶端和auth服務器之間直接進行基於密碼的用戶令牌交換。我認爲將口令授權擴展到其他形式的認證是非常自然的。如果不是這封信的話,它本着規範的精神,所以如果你擁有關係的雙方,沒有什麼可以出錯的。 Spring OAuth並沒有明確地支持以這種方式擴展密碼授權的任何東西,但它並不難(這實際上只是關於/ token端點的安全性)。我見過的另一種方法是堅持使用密碼授權協議,但將「密碼」作爲一次性令牌,客戶端只有通過了解用戶使用其中一種替代方式進行身份驗證後才能獲得該令牌。

+0

考慮您的第一句話:「客戶端憑證授予」創建啓用預授權客戶。這難道不是那麼完美嗎? –

+0

不適用於用戶令牌(不是來自規範的術語,而是我認爲有用的術語)。客戶端憑據授予不會導致綁定到特定用戶的令牌。 –

+0

你說得對,這種綁定不在規格範圍內。但是如果需要的話,這可以通過最小程度的擴展來完成。 –

相關問題