2017-02-09 40 views
0

可以說我在我的Spring應用程序中有多個身份驗證提供程序。如:控制彈簧安全性如何運行身份驗證提供程序的順序和邏輯

@Autowired 
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
    auth.authenticationProvider(AAuthenticationProvider()); 
    auth.authenticationProvider(BAuthenticationProvider()); 
    auth.authenticationProvider(CAuthenticationProvider());  
} 

默認情況下,spring security將嘗試這些提供程序,直到提供了非空響應。

問題:我可以自定義這種行爲,我可以更改列表提供程序的運行順序和邏輯嗎?

看起來ProviderManager負責運行這個邏輯。是否有可能重寫這種行爲?

回答

0

我不認爲有一個方便的方式來操縱訂單,而不是僅僅改變您在其中添加提供商的訂單順序auth.authenticationProvider

構建器每次調用auth.authenticationProvider時都有一個ArrayList結尾。評估按照這些提供者添加到列表中的順序完成。

希望這會有所幫助!

0

我找不到Spring的任何直接解決方案。我希望能夠找到諸如創建自定義ProviderManager的能力。我的解決方法是創建一個父認證提供程序與一個父UserDetailsS​​ervice我可以控制所有UserDetailsS​​ervices的流。

您配置類將包括以下內容:

@Configuration 
@EnableWebSecurity 
public class SecConfig extends WebSecurityConfigurerAdapter { 
@Autowired 
UserDetailsService parentUserDetailsService; 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
     auth.authenticationProvider(ParentAuthenticationProvider());  
    } 

    @Bean 
    public DaoAuthenticationProvider ParentAuthenticationProvider() { 
     DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); 
    authenticationProvider.setUserDetailsService(parentUserDetailsService); 
    return authenticationProvider; 
} 
} 

父服務將有機會獲得所有的兒童服務。所以它會是這個樣子:

@Service 
public class ParentUserDetailsService implements UserDetailsService { 

@Autowired 
UserDetailsService aUserDetailsService; 

@Autowired 
UserDetailsService bUserDetailsService; 

@Autowired 
UserDetailsService cUserDetailsService; 

@Override 
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 

    UserDetails user = null; 
    /* your logic will be here. 
     You iterate through all of the services 
     or have some conditional flow. the sky is your limit! 
    */ 
    // For Example 
    if(cond1) 
     user = aUserDetailsService.loadUserByUsername(username); 
    else(cond2){ 
     try{ 
      user = bUserDetailsService.loadUserByUsername(username); 
     }catch(Exception e){ 
     user = cUserDetailsService.loadUserByUsername(username); 
     } 
    } 

    return user; 

} 

我不知道這是否是最優化的解決方案,但它在我的情況下運作良好。

相關問題