繁体   English   中英

控制Spring Security如何运行AuthenticationProviders列表的顺序和逻辑

[英]Control the order and logic of how spring security runs the list of AuthenticationProviders

可以说我的Spring应用程序中有多个AuthenticationProvider 如 :

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

默认情况下,spring security将按顺序尝试这些提供程序,直到提供非空响应为止。

问题 :是否可以在可以更改列表提供程序的运行顺序和逻辑的地方自定义此行为?

似乎ProviderManager以某种方式负责运行此逻辑。 是否有可能重写此行为?

我认为没有一种简便的方法来操作订单,而不仅仅是更改使用auth.authenticationProvider添加提供程序的订单顺序。

每次调用auth.authenticationProvider时,构建器都会在其末尾添加一个ArrayList。 评估的顺序与将这些提供者也添加到列表中的顺序相同。

希望这可以帮助!

我找不到来自Spring的任何直接解决方案。 我希望找到诸如创建自定义ProviderManager的功能 我的解决方法是使用一个父UserDetailsS​​ervice创建一个父authenticationProvider ,在其中我可以控制所有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;

}

我不确定这是否是最佳解决方案,但在我的情况下效果很好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM