2016-04-05 96 views
0

我想問一些關於Spring Security中我的問題的幫助。 我有一個要求,我必須根據用戶選擇的選項驗證登錄憑證。選項1將通過第三方服務驗證登錄用戶。選項2將是使用數據庫認證級別的正常驗證。我怎樣才能實現這個?在Spring Security中實現自定義身份驗證

回答

5

總體戰略

  1. 提供org.springframework.security.authentication.AuthenticationProvider定製實現,鑑定委派到相應的後端(第三方服務,另一個AuthenticationProvider等)。
  2. 將用戶選擇的選項傳遞給自定義AuthenticationProvider以使其能夠選擇正確的身份驗證後端。
  3. 將自定義AuthenticationProvider配置爲默認身份驗證提供程序。

步驟1:實施AuthenticationProvider

AuthenticationProvider是具有單個方法的接口。因此,自定義實現可能看起來像:

class DelegatingAuthenticationProvider implements AuthenticationProvider { 
    @Autowired 
    private ThirdPartyAuthenticationService service; 

    @Autowired 
    @Qualifier("anotherAuthenticationProvider") 
    private AuthenticationProvider provider; 

    @Override 
    public Authentication authenticate(final Authentication authentication) throws AuthenticationException { 
    // Get the user selection. 
    String selection = (String) authentication.getDetails(); 

    // Take action depending on the selection. 
    Authentication result; 
    if("ThirdParty".equals(selection)) { 
     // Authenticate using "service" and generate a new 
     // Authentication "result" appropriately. 
    } 
    else { 
     // Authenticate using "provider" and generate a new 
     // Authentication "result" appropriately. 
    } 

    return result; 
    } 
} 

步驟2:將用戶選擇的AuthenticationProvider

AuthenticationProvider執行上述從的details屬性拾取所述用戶選擇Authentication對象。據推測,用戶選擇必須從HttpServletRequest中選取,並在調用AuthenticationProvider之前將其添加到Authentication對象。這意味着,另一個組件可以訪問AuthenticationHttpServletRequest對象,並在需要實施AuthenticationProvider之前調用。

Authentication對象是通過執行AbstractAuthenticationProcessingFilter創建的。該類有一個名爲attemptAuthentication的方法,它接受一個HttpServletRequest對象並返回一個Authentication對象。所以看起來這將是一個很好的候選人來實施需要的東西。對於基於用戶名 - 密碼的認證,實施等級爲UsernamePasswordAuthenticationFilter。該類返回UsernamePasswordAuthenticationToken的新實例,該實例是Authentication的實現。所以,擴展UsernamePasswordAuthenticationFilter的類應該足夠了。

class ExtendedUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { 
    @Override 
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { 
    ... 
    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, password); 
    authentication.setDetails(obtainUserSelection(request)); 

    ... 

    return authentication; 
    } 
} 

obtainUserSelection是一種私人方法,可以將用戶選擇從請求中提取出來。

第3步:配置

配置在春季安全配置AuthenticationProvider和濾波器實現。具體步驟取決於是使用XML還是Java配置。

+0

哇..感謝manish!這是一個學習春季安全的好機會。順便說一句,這是我第一次實施。你能指點我一個關於實現ExtendedUsernamePasswordAuthenticationFilter的教程網站嗎?請:) –

+0

您可以查看[UsernamePasswordAuthenticationFilter'的官方實現](https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/security /web/authentication/UsernamePasswordAuthenticationFilter.java)。 – manish

相關問題