I have 2 authentication manager in my application.
@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;
}
}
PreAuthenticatedFilter class,
@Component("preAuthenticatedFilter")
public class WebPreAuthenticatedProcessingFilter extends AbstractPreAuthenticatedProcessingFilter {
@Override
@Autowired
@Qualifier("webAuthManager")
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authenticationManager);
}
}
WebAuthenticationManager class,
@Service
@ComponentScan
@Component("webAuthManager")
public class WebAuthenticationManager implements AuthenticationManager {
@Override
public Authentication authenticate(Authentication authentication) {
// ...
}
}
And the xml file which has one more 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="(&(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>
Even I use the Qualifier, I get the below exception.
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
You need to setup 2 Providers, one for Ldap and one for Web. AuthenticationManager (if it's ProviderManager
instance) will select corresponding Provider for authentication. Manager basically manages list of Providers, that do actual job.
Like (I guess its easier to configure everything in one place?):
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth // you have to prepare following beans also
.authenticationProvider(getLdapAuthenticationProvider())
.authenticationProvider(getWebAuthenticationProvider());
}
See http://docs.spring.io/spring-security/site/docs/4.0.2.RELEASE/reference/htmlsingle/#core-services-authentication-manager
Solution for XML base: If you required more than 1 authentication manager then you can define it but got warning "overriding globally registered authenticationmanager" that's mean all Element : HTTP are match with last defined authenticationmanager.
So you can try this for XML base and security v4.0+ required.
Solution: You must use "Id" attribute in authenticationmanager and same id define in "HTTP" element in "authentication-manager-ref" attribute. So then security fetch suitable authenticationmanager for particular HTTP request.
Sample code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd">
<!-- HTTP basic authentication for Rest API when match url pattern="/api/**" -->
<security:http realm="API" pattern="/api/**"
use-expressions="true" auto-config="true" create-session="stateless"
authentication-manager-ref="APIAuthenticationManager">
<security:intercept-url pattern="/**" access="hasRole('USER')" />
<security:http-basic />
<security:csrf disabled="true" />
</security:http>
<security:authentication-manager id="APIAuthenticationManager"
alias="APIAuthenticationManager">
<security:authentication-provider user-service-ref="APIAuthenticationProvider" />
</security:authentication-manager>
<bean class="com.example.security.api.APIAuthentication"
id="APIAuthenticationProvider">
</bean>
<!-- From Login authentication for web portal when match url parrern ="/web/**" -->
<security:http realm="WEB" auto-config="true"
use-expressions="true" create-session="always"
authentication-manager-ref="userAuthenticationManager">
<security:intercept-url pattern="/resources/**" access="permitAll" />
<security:intercept-url pattern="/web/login" access="hasRole('ROLE_ANONYMOUS')" />
<security:intercept-url pattern="/web/dashboard**" access="hasRole('USER')" method="GET" />
<!-- Set login, landing page, Successful, unsuccessful ... -->
<security:form-login login-page="/web/login"
default-target-url="/web/dashboard"
login-processing-url="/web/dashboard"
always-use-default-target="true"
authentication-failure-url="/web/login?error"
username-parameter="email"
password-parameter="encryptedPassword" />
<!-- Set logout detail -->
<security:logout logout-url="/web/logout"
logout-success-url="/index.jsp"
delete-cookies="JSESSIONID"
invalidate-session="true" />
<security:csrf/>
</security:http>
<security:authentication-manager id="userAuthenticationManager" alias="userAuthenticationManager">
<security:authentication-provider user-service-ref="userAuthenticationProvider" />
</security:authentication-manager>
<bean class="com.example.security.web.UserAuthentication"
id="userAuthenticationProvider">
</bean>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With