1

我正在尝试使用 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
4

2 回答 2

1

您正在使用<openid-login>命名空间元素,该元素将自动尝试查找UserDetatailsService. 只是将其他 bean 添加到配置中本身不会有任何区别。

正如错误消息所说,您需要直接在命名空间元素中提供一个 ID。使用user-service-ref属性(参见命名空间附录):

<openid-login user-service-ref="openIDUserDS">
   ...

并取出openIDAuthenticationProvider豆子。

于 2012-10-18T14:17:37.723 回答
0

正如异常堆栈跟踪所示

nested exception is org.springframework.context.ApplicationContextException: More than one UserDetailsService registered. Please use a specific Id reference in   or  elements.

问题在于元素 -

  <user-service id="userDetailsService">
    <user name="abdellah" password="32fe5bbf04adc744455c92fa7b71e9dca8ce729c" authorities="ROLE_CLOUD_USER" />
    <user name="guest"    password="35675e68f4b5af7b995d9205ad0fc43842f16450" authorities="ROLE_CLOUD_USER" />
  </user-service>

这导致了冲突。看到你的配置,既然你不是指这个bean,请删除它。错误应该得到解决。

于 2012-10-18T08:05:50.117 回答