Results 1 to 5 of 5

Thread: Multiple authentication-managers Defined But Only the Last One Is Applied

Hybrid View

  1. #1
    Join Date
    Mar 2012
    Location
    Salt Lake City, UT
    Posts
    4

    Default Multiple authentication-managers Defined But Only the Last One Is Applied

    With the creation of the authentication-manager-ref attribute of the http element, I assumed that we were free to define multiple authentication managers that could be used by different http definitions.

    However, in practice Spring Security only seems to care about the last authentication-manager definition in the XML config file. Is this correct behavior or a bug?

    To illustrate my point, I created two http blocks:

    Code:
        <http pattern="/remoting/**" use-expressions="true" authentication-manager-ref="remotingAuthenticationManager">
            <intercept-url pattern="/**" access="hasAnyRole('ROLE_LIMITED_REMOTE_USER','ROLE_GODMODE_REMOTE_USER')"/>
            <anonymous enabled="false"/>
            <http-basic/>
        </http>
    
        <http pattern="/**" use-expressions="true" disable-url-rewriting="true" authentication-manager-ref="adminAuthenticationManager">
            <form-login login-page="/login" authentication-failure-url="/failure"/>
            <logout logout-url="/logout" logout-success-url="/login"/>
            <access-denied-handler error-page="/denied"/>
    
            <intercept-url pattern="/denied" access="permitAll"/>
            <intercept-url pattern="/failure" access="permitAll"/>
            <intercept-url pattern="/login" access="permitAll"/>
            <intercept-url pattern="/**" access="hasAnyRole('ROLE_SUPER_USER','ROLE_ADMIN')"/>
        </http>
    As you can see, the first block references an authentication manager bean with an id of remotingAuthenticationManager while the second block references an authentication manager bean with an id of adminAuthenticationManager.

    My authentication managers are defined as follows:

    Code:
        <authentication-manager alias="adminAuthenticationManager">
            <authentication-provider>
                <user-service>
                    <user name="stanFox" password="stan-password" authorities="ROLE_SUPER_USER"/>
                    <user name="marie" password="marie-password" authorities="ROLE_ADMIN"/>
                    <user name="navin" password="navin-password" authorities="ROLE_LOSER_USER"/>
                </user-service>
            </authentication-provider>
        </authentication-manager>
    
        <authentication-manager alias="remotingAuthenticationManager">
            <authentication-provider>
                <user-service>
                    <user name="blair" password="blair-password" authorities="ROLE_LIMITED_REMOTE_USER"/>
                    <user name="clay" password="clay-password" authorities="ROLE_GODMODE_REMOTE_USER"/>
                    <user name="julian" password="julian-password" authorities="ROLE_LOSER_USER"/>
                </user-service>
            </authentication-provider>
        </authentication-manager>
    When I deploy my application with the above configuration, I can authenticate with my services at /remoting/** just fine because the remotingAuthenticationManager is working. However, I cannot log into my admin interface at /** using the credentials defined by the adminAuthenticationManager.

    If I flip the two authentication manager definitions so that the adminAuthenticationManager bean is the last one in the XML config file, then I can log in fine with those credentials into my admin interface at /** but then the credentials defined in the remotingAuthenticationManager bean do not work when I try to authenticate with my services at /remoting/**.

    To prove this further, I have created a simple proof of concept and checked it into Github here: https://github.com/monger/Spring-Sec...h-Manager-Test

    I have created some instructions and some integration tests so you can simply run the following maven goal to see the results:

    mvn integration-test

    If I am misunderstanding the purpose of the authentication-manager-ref attribute, I would love to know. However, if this is a bug I would really love to see a fix because I have an actual use case that requires multiple authentication managers -- a requirement that cannot be satisfied by stacking authentication providers in a single authentication manager.

    Again -- to be clear I just want to know whether I am misunderstanding the purpose of the authentication-manager-ref attribute or whether the behavior I noted above is a bug.

    Thanks!

  2. #2
    Join Date
    Jan 2008
    Posts
    1,826

    Default

    I think it is more of a misunderstanding with creating two <authentication-manager> elements. If you create two authentication-manager elements the second one overrides the other. You will notice something like the following in your logs when you startup.

    Code:
    WARN  org.springframework.beans.factory.parsing.FailFastProblemReporter - Configuration problem: Overriding globally registered AuthenticationManager
    This is clearly not ideal, so I logged SEC-1937. In the meantime, you can create the second AuthenticationManager using standard spring beans. Something like this should work:

    Code:
    <authentication-manager alias="adminAuthenticationManager">
        <authentication-provider>
            <user-service>
                <user name="stanFox" password="stan-password" authorities="ROLE_SUPER_USER"/>
            </user-service>
        </authentication-provider>
    </authentication-manager>
    
    <user-service id="remotingUds">
        <user name="blair" password="blair-password" authorities="ROLE_LIMITED_REMOTE_USER"/>
    </user-service>
    <beans:bean id="remotingAuthenticationManager" class="org.springframework.security.authentication.ProviderManager">
        <beans:constructor-arg>
            <beans:list>
                <beans:bean class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"
                    p:userDetailsService-ref="remotingUds"/>
            </beans:list>
        </beans:constructor-arg>
    </beans:bean>
    PS: Thanks for the very thorough write up.

    Cheers,
    Rob Winch - @rob_winch
    Spring Security Lead
    Pivotal

  3. #3
    Join Date
    Mar 2012
    Location
    Salt Lake City, UT
    Posts
    4

    Default

    Rob, you made my day! I sincerely appreciate your quick response.

    Your work-around works perfectly in my real-world web app. I thank you and my team thanks you.

    I will be watching SEC-1937.

  4. #4
    Join Date
    Jan 2008
    Posts
    1,826

    Default

    Luke points out on the JIRA that you should be using the id rather than the alias attribute. Can you try that and see if it fixes your problem w/ using multiple AuthenticaitonManager instances.
    Rob Winch - @rob_winch
    Spring Security Lead
    Pivotal

  5. #5
    Join Date
    Mar 2012
    Location
    Salt Lake City, UT
    Posts
    4

    Default

    Yeah I just switched the "alias" attributes out for "id" attributes and then ran the integration tests and they all passed.

    Luke was right.

    Thanks to both of you!

Tags for this Thread

Posting Permissions

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