我正在尝试使用 spring security 3.1 自定义身份验证以同时使用表单和 OpenID 登录。
这是我的 spring-security.xml 文件:
<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>
您可以看到我在“authentication-manager”中有两个提供程序元素,一个用于每种类型的身份验证。OpenID 提供者配置了一个UserDetailService
名为openIDUserDS
.
当我部署应用程序时,我得到了这个异常:
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