Results 1 to 8 of 8

Thread: Only one UserDetails allowed: why?

  1. #1
    Join Date
    Jan 2008
    Posts
    248

    Default 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. #2
    Luke Taylor is offline Senior Member Acegi Security System TeamSpring Team
    Join Date
    Aug 2004
    Location
    Glasgow, Scotland
    Posts
    3,449

    Default

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

  3. #3
    Join Date
    Jan 2008
    Posts
    248

    Default 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

  4. #4
    Luke Taylor is offline Senior Member Acegi Security System TeamSpring Team
    Join Date
    Aug 2004
    Location
    Glasgow, Scotland
    Posts
    3,449

    Default

    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.

  5. #5
    Join Date
    Jan 2008
    Posts
    248

    Default 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

  6. #6
    Luke Taylor is offline Senior Member Acegi Security System TeamSpring Team
    Join Date
    Aug 2004
    Location
    Glasgow, Scotland
    Posts
    3,449

    Default

    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.

  7. #7
    Join Date
    Jan 2008
    Posts
    248

    Default 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

  8. #8
    Luke Taylor is offline Senior Member Acegi Security System TeamSpring Team
    Join Date
    Aug 2004
    Location
    Glasgow, Scotland
    Posts
    3,449

    Default

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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •