I am trying to customize authentication with spring security 3.1 to use both form and OpenID login.
Here is my spring-security.xml file:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/login.htm" access="permitAll" />
<intercept-url pattern="/loginfailed*" access="permitAll" />
<intercept-url pattern="/loginopenidfailed*" access="permitAll" />
<intercept-url pattern="/home.htm" access="permitAll" />
<intercept-url pattern="/**.htm" access="hasRole('ROLE_CLOUD_USER')" />
<form-login login-page="/login.htm"
default-target-url="/admin.htm"
authentication-failure-url="/loginfailed.htm"
always-use-default-target="true"/>
<logout logout-url="/logout.htm" logout-success-url="/home.htm" />
<openid-login authentication-failure-url="/loginopenidfailed.htm">
<attribute-exchange>
<openid-attribute name="email" type="http://schema.openid.net/contact/email" required="true" count="2"/>
<openid-attribute name="name" type="http://schema.openid.net/namePerson/friendly" />
</attribute-exchange>
</openid-login>
</http>
<!--Authentication Manager -->
<authentication-manager alias="authenticationManager">
<authentication-provider ref="daoAuthenticationProvider"/>
<authentication-provider ref="openIDAuthenticationProvider"/>
</authentication-manager>
<!--dao authentication provider -->
<beans:bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userService" />
<beans:property name="passwordEncoder">
<beans:bean class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" />
</beans:property>
</beans:bean>
<!--openID authentication provider -->
<beans:bean id="openIDAuthenticationProvider" class="org.springframework.security.openid.OpenIDAuthenticationProvider">
<beans:property name="userDetailsService" ref="openIDUserDS" />
</beans:bean>
<!--openID UserDetail -->
<beans:bean id="openIDUserDS" class="test.security.CloudOpenIDUserDS"/>
<user-service id="userDetailsService">
<user name="abdellah" password="32fe5bbf04adc744455c92fa7b71e9dca8ce729c" authorities="ROLE_CLOUD_USER" />
<user name="guest" password="35675e68f4b5af7b995d9205ad0fc43842f16450" authorities="ROLE_CLOUD_USER" />
</user-service>
</beans:beans>
You can see that I have two provider elements in the “authentication-manager”, one for each type of authentication. The OpenID provider is configured with a UserDetailService bean called openIDUserDS.
When I deploy the application, I get this exception:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChains': Cannot resolve reference to bean 'org.springframework.security.web.DefaultSecurityFilterChain#0' while setting bean property 'sourceList' with key [0]; nested exception is
... Snip to root cause ...
Caused by: org.springframework.context.ApplicationContextException: More than one UserDetailsService registered. Please use a specific Id reference in <remember-me/> <openid-login/> or <x509 /> elements.
at org.springframework.security.config.http.UserDetailsServiceFactoryBean.getUserDetailsService(UserDetailsServiceFactoryBean.java:102)
at org.springframework.security.config.http.UserDetailsServiceFactoryBean.authenticationUserDetailsService(UserDetailsServiceFactoryBean.java:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:149)
... 95 more
You’re using the
<openid-login>namespace element which will automatically try and look for aUserDetatailsService. Just adding other beans to the configuration won’t make any difference by itself.As the error message says, you need to supply an ID directly in the namespace element. Use the
user-service-refattribute (see the namespace appendix):and remove the
openIDAuthenticationProviderbean.