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:
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.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>
My authentication managers are defined as follows:
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.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>
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!


Reply With Quote
