Announcement Announcement Module
Collapse
No announcement yet.
Only one UserDetails allowed: why? Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Only one UserDetails allowed: why?

    Hi,

    Trying to upgrade to Spring Security on an Appfuse based project I'm running into a problem where I have a UserDetails interface applied and Appfuse does also. Apparently, now: more than one UserDetails class is not allowed in our application context. Spring Security checks for the existence of UserDetails by type and throws an error if it finds more than one. Since Appfuse uses its own, I keep getting an error saying I should have only one UserDetails class.

    Even though having two of them in my project seems a bit silly, it would require me to rip open Appfuse to get rid of that one. Not something I want to do.

    I don't see why this is required because I can easily distinguish between appropriate UserDetails beans by bean id. In Acegi this was not a requirement and I never had any problems. Can this be changed for 2.0.2?

    Kind regards,

    Marc

  • #2
    Please clarify what error you're talking about. You can normally have as many UserDetails implementations as you want.

    Comment


    • #3
      Re: error

      In ConfigUtils.class line 105:
      else if (services.length > 1) {
      throw new IllegalArgumentException("More than one UserDetailsService registered. Please " +
      "use a specific Id in your configuration");
      }

      Cheers,

      Marc

      Comment


      • #4
        Ok. So you're talking about UserDetailsServices, not UserDetails implementations.

        As the error message says, that should only be called if a bean is trying to locate a UserDetailsServices because one hasn't been specified by Id. If there is more than one, it doesn't know which one to use.

        Please attach your configuration file.

        Comment


        • #5
          My security.xml

          Hi,

          Yeah. Here's the security.xml

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

              <http auto-config="true" lowercase-comparisons="false">
                  <intercept-url pattern="/imageuploader/*" filters="none" />
                  <intercept-url pattern="/images/*" filters="none" />
                  <intercept-url pattern="/css/*" filters="none" />
                  <intercept-url pattern="/js/*" filters="none" />
                  <intercept-url pattern="/admin/*" access="ROLE_ADMIN" />
                  <intercept-url pattern="/passwordHint.html*"
                      access="ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER" />
                  <intercept-url pattern="/signup.html*"
                      access="ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER" />
                  <intercept-url pattern="/a4j.res/*.html*"
                      access="ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER" />
                  <intercept-url pattern="/account/*"
                      access="ROLE_VENDOR,ROLE_USER" />
                  <intercept-url pattern="/account/offers/*"
                      access="ROLE_VENDOR,ROLE_ADMIN" />
                  <intercept-url pattern="/admin/*" access="ROLE_ADMIN" />
                  <!-- APF-737, OK to remove line below if you're not using JSF -->
                  <intercept-url pattern="/**/*.html*"
                      access="ROLE_ADMIN,ROLE_USER" />
                  <form-login login-page="/login.html"
                      authentication-failure-url="/login.html?error=true"
                      login-processing-url="/j_security_check" />
                  <logout logout-success-url="/home.html" />
                  <!-- <remember-me services-ref="rememberMeServices" key="e37f4b31-0c45-11dd-bd0b-0800200c9a66"/> -->
              </http>
              <authentication-provider user-service-ref="usorManager">
                  <!-- <password-encoder ref="passwordEncoder"/>-->
              </authentication-provider>
           
          <beans:bean id="authenticationProcessingFilter"
              class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
              <custom-filter position="AUTHENTICATION_PROCESSING_FILTER" />
              <beans:property name="authenticationManager" ref="authenticationManager" />
              <beans:property name="filterProcessesUrl">
                <beans:value>/login_security_check</beans:value>
              </beans:property>
              <beans:property name="defaultTargetUrl">
                <beans:value>/home.html</beans:value>
              </beans:property>
              <beans:property name="authenticationFailureUrl">
                <beans:value>/login.html</beans:value>
              </beans:property>
              <beans:property name="rememberMeServices" ref="rememberMeServices" />
            </beans:bean>
           

              <!-- Override the default password-encoder (SHA) by uncommenting the following and changing the class -->
              <!-- <bean id="passwordEncoder" class="org.springframework.security.providers.encoding.ShaPasswordEncoder"/> -->
              <!-- <global-method-security>
                  <protect-pointcut expression="execution(* *..service.UserManager.getUsers(..))" access="ROLE_ADMIN"/>
                  <protect-pointcut expression="execution(* *..service.UserManager.removeUser(..))" access="ROLE_ADMIN"/>
                  </global-method-security> -->
                  
              <!-- ============= Security ============= -->    
              <beans:bean id="rememberMeProcessingFilter"
                  class="org.springframework.security.ui.rememberme.RememberMeProcessingFilter">
                  <custom-filter after="AUTHENTICATION_PROCESSING_FILTER" />
                  
                  <beans:property name="rememberMeServices" ref="rememberMeServices" />
              </beans:bean>
              
              <beans:bean id="rememberMeServices"
                  class="nl.project.service.impl.RememberMeManagerImpl">
                  <beans:property name="userDetailsService" ref="usorManager" />
                  <beans:property name="key"
                      value="e37f4b31-0c45-11dd-bd0b-0800200c9a66" />
                  <beans:property name="parameter" value="rememberMe" />
                  <beans:property name="userDao" ref="usorDao" />
                  <beans:property name="alwaysRemember" value="true" />
              </beans:bean>
              
              <beans:bean id="rememberMeAuthenticationProvider"
                  class="org.springframework.security.providers.rememberme.RememberMeAuthenticationProvider">
                  <beans:property name="key"
                      value="e37f4b31-0c45-11dd-bd0b-0800200c9a66" />
              </beans:bean>
              <!-- ============= End Security ============= -->
              <!--  ============ Captcha integration ====== -->

              <beans:bean id="captchaProducer"
                  class="com.google.code.kaptcha.impl.DefaultKaptcha">
                  <beans:property name="config">
                      <beans:bean class="com.google.code.kaptcha.util.Config">
                          <beans:constructor-arg type="java.util.Properties">
                              <beans:value>
                                  kaptcha.background.clear.from=255,140,0
                              </beans:value>
                          </beans:constructor-arg>
                      </beans:bean>
                  </beans:property>
              </beans:bean>
              <!-- ============== End Captcha ============= -->
          </beans:beans>
          Thanks,

          Marc

          Comment


          • #6
            Hard to say without the stacktrace, but I'd guess you need to remove the "auto-config" which will automatically add remember-me provision and that requires a UserDetailsService.

            Comment


            • #7
              Autoconfig

              Well,

              I actually stepped through it and the extra UserDetailsService is created by Appfuse which I use as a base. The point is, why should there be only one UserDetailsService? This wasn't a requirement in Acegi.

              I can understand that a minimum level of configuration for autoconfig might lead to "it" looking for a UserDetailsService by type and therefore only accept one. But why not then add the option to specify one?

              Cheers,

              Marc

              Comment


              • #8
                You can specify one. Remove the auto-config, configure remember-me explicitly and use the user-service-ref attribute.

                Comment

                Working...
                X