Spring Security Java - 多个身份验证管理器 - 找到2个bean错误

use*_*872 4 spring spring-security spring-boot

我的应用程序中有2个身份验证管理器.

@Configuration
@EnableWebMvcSecurity
@ComponentScan
@ImportResource("classpath:security-context.xml")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private AuthenticationEntryPoint webAuthenticationEntryPoint = null;

    private AuthenticationManager webAuthenticationManager = null;

    private final webPreAuthenticatedProcessingFilter webPreAuthenticatedProcessingFilter;


    public WebSecurityConfig() {
        super();
        webPreAuthenticatedProcessingFilter = new webPreAuthenticatedProcessingFilter();
        webPreAuthenticatedProcessingFilter.setAuthenticationManager(webAuthenticationManager);
        webPreAuthenticatedProcessingFilter.setInvalidateSessionOnPrincipalChange(true);
        webPreAuthenticatedProcessingFilter.setContinueFilterChainOnUnsuccessfulAuthentication(Boolean.FALSE);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()
            .antMatchers("/login", "/logoffUser", "/sessionExpired", "/error").permitAll()
            .anyRequest().authenticated().and().rememberMe().and().httpBasic()
            .authenticationEntryPoint(webAuthenticationEntryPoint).and()
            .addFilterAfter(webPreAuthenticatedProcessingFilter, webPreAuthenticatedProcessingFilter.class).csrf()
            .disable().logout().deleteCookies("JSESSIONID").logoutSuccessUrl("/logoff").invalidateHttpSession(true);
    }

    @Autowired
    @Qualifier("webAuthManager")
    public void setwebAuthenticationManager(AuthenticationManager webAuthenticationManager) {

        this.webAuthenticationManager = webAuthenticationManager;
        webPreAuthenticatedProcessingFilter.setAuthenticationManager(this.webAuthenticationManager);
    }

    @Autowired
    public void setwebAuthenticationEntryPoint(AuthenticationEntryPoint webAuthenticationEntryPoint) {

        this.webAuthenticationEntryPoint = webAuthenticationEntryPoint;
    }

}
Run Code Online (Sandbox Code Playgroud)

PreAuthenticatedFilter类,

@Component("preAuthenticatedFilter")
public class WebPreAuthenticatedProcessingFilter extends AbstractPreAuthenticatedProcessingFilter {   
    @Override
    @Autowired
    @Qualifier("webAuthManager")
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        super.setAuthenticationManager(authenticationManager);
    }
}
Run Code Online (Sandbox Code Playgroud)

WebAuthenticationManager类,

@Service
@ComponentScan
@Component("webAuthManager")
public class WebAuthenticationManager implements AuthenticationManager {


    @Override
    public Authentication authenticate(Authentication authentication) {

       // ...

    }
}
Run Code Online (Sandbox Code Playgroud)

并且xml文件中还有一个authnetication manager,

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:security="http://www.springframework.org/schema/security"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security 
                        http://www.springframework.org/schema/security/spring-security-3.2.xsd">

    <bean id="ldapConfig" class="com.wellmanage.mnpi.core.jms.LdapConfig">
        <constructor-arg name="user" value="${ldap.conn.user}"/>
        <constructor-arg name="sid" value="${ldap.conn.sid}"/>
    </bean>

    <security:ldap-server url="${ldap.url}" 
        manager-dn="${ldap.conn.user}" manager-password="#{ldapConfig.getPassword()}" />

    <security:authentication-manager alias="ldapAuthManager" id="ldapAuthManager">
        <security:ldap-authentication-provider
            user-search-filter="(&amp;(sAMAccountName={0})(objectclass=organizationalPerson))"
            user-search-base="OU=${ldap.user-search-base.name}"
            group-search-filter="(member={0})" group-search-base="OU=Global-Groups"
            group-role-attribute="cn"/>
    </security:authentication-manager>

    <bean id="mq.accessDecisionManager"
        class="org.springframework.security.access.vote.AffirmativeBased">
        <constructor-arg>
            <list>
                <bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"/>
            </list>
        </constructor-arg>
    </bean>
</beans>
Run Code Online (Sandbox Code Playgroud)

即使我使用限定符,我也得到以下异常.

Exception in thread "main" org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:133)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:474)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at com.wellmanage.mnpi.Application.main(Application.java:60)
Caused by: org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.initialize(TomcatEmbeddedServletContainer.java:98)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.<init>(TomcatEmbeddedServletContainer.java:75)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getTomcatEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:378)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:155)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:157)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130)
    ... 5 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalArgumentException: Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found [webAuthManager, ldapAuthManager]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.boot.context.embedded.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:209)
    at org.springframework.boot.context.embedded.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:165)
    at org.springframework.boot.context.embedded.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:160)
    at org.springframework.boot.context.embedded.ServletContextInitializerBeans.addAdaptableBeans(ServletContextInitializerBeans.java:143)
    at org.springframework.boot.context.embedded.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:74)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getServletContextInitializerBeans(EmbeddedWebApplicationContext.java:234)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.selfInitialize(EmbeddedWebApplicationContext.java:221)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.access$000(EmbeddedWebApplicationContext.java:84)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext$1.onStartup(EmbeddedWebApplicationContext.java:206)
    at org.springframework.boot.context.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:54)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5156)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalArgumentException: Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found [webAuthManager, ldapAuthManager]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
    ... 26 more
Caused by: java.lang.IllegalArgumentException: Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found [webAuthManager, ldapAuthManager]
    at org.springframework.util.Assert.isTrue(Assert.java:65)
    at org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration.lazyBean(AuthenticationConfiguration.java:112)
    at org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration.getAuthenticationMangerBean(AuthenticationConfiguration.java:122)
    at org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration.getAuthenticationManager(AuthenticationConfiguration.java:81)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.authenticationManager(WebSecurityConfigurerAdapter.java:236)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.getHttp(WebSecurityConfigurerAdapter.java:178)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:283)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:68)
    at com.wellmanage.mnpi.security.WebSecurityConfig$$EnhancerBySpringCGLIB$$c6c13351.init(<generated>)
    at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.init(AbstractConfiguredSecurityBuilder.java:367)
    at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:320)
    at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:39)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain(WebSecurityConfiguration.java:98)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$eb0d5df1.CGLIB$springSecurityFilterChain$3(<generated>)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$eb0d5df1$$FastClassBySpringCGLIB$$622492d6.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:309)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$eb0d5df1.springSecurityFilterChain(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
    ... 27 more
Run Code Online (Sandbox Code Playgroud)

Igo*_*nov 9

您需要设置2个提供程序,一个用于Ldap,一个用于Web.AuthenticationManager(如果是ProviderManager实例)将选择相应的Provider进行身份验证.经理基本上管理提供者列表,做实际工作.

喜欢(我想它更容易在一个地方配置所有东西?):

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth  // you have to prepare following beans also
        .authenticationProvider(getLdapAuthenticationProvider())
        .authenticationProvider(getWebAuthenticationProvider());
}
Run Code Online (Sandbox Code Playgroud)

请参阅http://docs.spring.io/spring-security/site/docs/4.0.2.RELEASE/reference/htmlsingle/#core-services-authentication-manager