[英]How to handle run time exceptions thrown by 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的功能 。 我的解决方法是使用一个父UserDetailsService创建一个父authenticationProvider ,在其中我可以控制所有UserDetailsServices的流。
您的配置类将包括以下内容:
@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.