当我们使用新版本的方法配置WebSecurityConfigurer
时,不需要再继承
WebSecurityConfigurerAdapter
类,转而使用@Bean
注解的方式,直接配置对应的bean,且Spring官方,也更加推荐使用这种方式。
在集成SpringSecurity
时,如果创建了多个AuthenticationProvider
接口的实现类bean,并且,是以如下所示方式配置的AuthenticationManager
bean,
在调用AuthenticationManager
bean时,就会出现StackOverFlow
异常。
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
debug代码时发现,是在SpringSecurity创建AuthenticationManager bean
时,使用了AOP
代理,实际是代理对象进入了死循环,具体代码如下
org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration#lazyBean
private <T> T lazyBean(Class<T> interfaceName) {
LazyInitTargetSource lazyTargetSource = new LazyInitTargetSource();
String[] beanNamesForType = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.applicationContext,
interfaceName);
if (beanNamesForType.length == 0) {
return null;
}
String beanName = getBeanName(interfaceName, beanNamesForType);
lazyTargetSource.setTargetBeanName(beanName);
lazyTargetSource.setBeanFactory(this.applicationContext);
ProxyFactoryBean proxyFactory = new ProxyFactoryBean();
proxyFactory = this.objectPostProcessor.postProcess(proxyFactory);
proxyFactory.setTargetSource(lazyTargetSource);
return (T) proxyFactory.getObject();
}
出现死循环的原因还没搞清楚,按理说出现多个AuthenticationProvider
的实现类应该是很正常的操作,一般的项目都有多种认证方式,可能在新版Spring官方会解决这个问题。
既然知道了问题出在创建AuthenticationManager
bean上,那么我们就不走Spring Security
的方式,直接自己来创建
@Bean
public AuthenticationManager authenticationManager(List<AuthenticationProvider> authenticationProviders) throws Exception {
return new ProviderManager(authenticationProviders);
}
入参为AuthenticationProvider
类型的集合,Spring
会自动将这个类型的所有bean收集起来,封装成集合,传入。
这样在使用AuthenticationManager
时,就不会再出现StackOverFlow
异常了。
下面是demo
代码
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- dcrkj.com 版权所有 赣ICP备2024042791号-2
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务