Multiple login forms, different authentication managers - latest spring security - spring

I have a web application secured with Spring Security that needs two separate login forms. These two login forms need to be totally independent. I mean different login form, different url paths, be able to have a different authentication manager for each one too.
I have looked all over google and there are some ways to do this, but I have read and see some changes the last couple of weeks should make it easy to do this in the latest snapshot versions of the code.
First of all, as this bug is complete SEC-1171 we can now have multiple namespace elements to support multiple filter chain configurations.
Secondly, as this other bug shows SEC-1847 we are now able to select a custom authentication manager for each http tag.
The problem is that I have downloaded, compiled and everything but my xsd doesn't allow me to create a custom auth manager for each http tag, I also get errors whenever I try to change the login processing url or whenever I try to use a remember me key for each login form.
I started doing something like this:
<!-- Configure realm for administration users -->
<http pattern="/admin/**" auto-config="true" disable-url-rewriting="true" >
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<form-login login-page="/adminLogin.htm" default-target-url="/"
login-processing-url="/loginProcessing"
authentication-failure-url="/adminLogin.htm?error" />
<logout invalidate-session="true" logout-success-url="/" logout-url="/logout" />
<remember-me key="******" user-service-ref="userDetailsService" />
</http>
<!-- Configure realm for standard users -->
<http auto-config="true" disable-url-rewriting="true">
<intercept-url pattern="/user/**" access="ROLE_USER" />
<form-login login-page="/login.htm" default-target-url="/"
login-processing-url="/loginProcessing"
authentication-failure-url="/login.htm?error" />
<logout invalidate-session="true" logout-success-url="/" logout-url="/logout" />
<remember-me key="******" user-service-ref="userDetailsService" />
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userDetailsService" >
<password-encoder ref="passwordEncoder"/>
</authentication-provider>
<authentication-provider>
<password-encoder ref="passwordEncoder"/>
<user-service>
<user name="ned" password="****" authorities="ROLE_USER" />
<user name="tom" password="****" authorities="ROLE_ADMIN"/>
</user-service>
</authentication-provider>
</authentication-manager>
I am using the latest snapshot of Spring Security 3.1.
As I said the ideal would be to be able to have two different login forms totally independent using the "new" way that was changed recently on these bugs.
Anybody has worked with this or has any idea?
Thanks in advance.

As you can see in commit log of October 30th'11 (2f67bb3) for SEC-1847, the authentication-manager-ref attribute can be added in http and global-method-security.

Ritesh, you are right, however, if I try to configure authentication-manager-ref in the http element, the follow exception occurs: org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute 'authentication-manager-ref' is not allowed to appear in element 'security:http'.
In header of my security.xml, I'm using http://www.springframework.org/schema/security/spring-security-3.1.xsd. If I browse to this URL, the xsd loaded declares the attribute authentication-manager-ref to the http element, but the xsd in spring-security-config-3.1.0.RC2.jar doesn't.
I created an issue in springsource jira-> https://jira.springsource.org/browse/SEC-1879 .
I replaced the xsd contained in spring-security-config-3.1.0.RC3.jar with a correct one and org.xml.sax.SAXParseException doesn't occur anymore, but it's not possible to declare two authentication-manager beans in security.xml.

Related

spring security xml explanation

I am a newbie to spring security. I want to understand what do following lines do to my web application
<security:http>
<security:intercept-url pattern="/**" access="ROLE_USER" />
<security:form-login />
<security:logout />
</security:http>
As far as I understand
intercept-url means when request to any resource having location matching the pattern specified in pattern property is received, show the form-login.
form-login means give me default form login
logout means give me default form logout
Please correct above points if they are wrong/inadequate. Also, can someone explain what does access="ROLE_USER" do?
Yes. For every intercept-url Spring Security will check if there is a logged user and if he/she has the needed role to access the url. In your case you match all requests. Notice that if you have multiple intercept-url they are evaluated in the order they are written in the config(if you put a wider intercept-url before some narrower one the later will not be evaluated).
2,3. You got it right.
To understand the access attribute, you have to know about authentication manager and provider. For example you can have:
<authentication-manager>
<authentication-provider>
<user-service>
<user name="myuser" password="mypass" authorities="ROLE_USER" />
<user name="myadmin" password="mypass" authorities="ROLE_ADMIN" />
</user-service>
</authentication-provider>
</authentication-manager>
(there other authentication-providers, for JDBC, LDAP...)
If you add another intercept-url:
<security:intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
it will be accessible by myadmin, but not by myuser.
only user with ROLE_USER in their granted authorites can access the resource.

Spring+ LDAP integration

I want to integrate LDAP in my spring application.
Requirement:- On request it should divert to my login page then ask for user/password. Then on submit it should authentication from LDAP.
Thanks
There is a special project in Spring called Spring Security for this purpose. The core functionality is built as a set of servlet API filters. There are multiple connectors for user's database (LDAP, DB, Active Directory, etc.) Here you can see how to add a basic conf. Your conf may looks like this:
<http use-expressions="true">
<intercept-url pattern="/**" access="isAuthenticated()" />
<form-login />
<logout />
</http>
Note that I prefer SpEL expressions for security rules. And here you can see how to add LDAP.
Hope it helps.
Along with that you also need other LDAP configuration like this
<ldap-server url="ldap://localhost:10389/dc=example,dc=com" />
<authentication-manager alias="authenticationManager"
erase-credentials="true">
<ldap-authentication-provider
user-dn-pattern="uid={0},ou=people" group-search-base="ou=groups"
group-search-filter="(members={0})">
</ldap-authentication-provider>
</authentication-manager>

How to adding Spring Security logout to system to logout users?

How to adding Spring Security logout to system to logout users? I am trying the following but it does not work:
<http use-expressions="true">
<intercept-url access="hasRole('ROLE_VERIFIED_MEMBER')" pattern="/ask-question**" />
<intercept-url pattern='/*' access='permitAll' />
<form-login default-target-url="/ask" />
<logout logout-success-url="/" />
<logout logout-url="/logout" logout-success-url="/login?logout_successful=1" />
<session-management session-fixation-protection="newSession">
<concurrency-control max-sessions="1"/>
</session-management>
</http>
I suggest to remove one of the <logout/> tags. Then, when you want to logout just navigate to /j_spring_security_logout. And if it's not working again, you should tell us what exactly is not working.
With two <logout> elements, I expect Spring is simply ignoring the second, which is the one wherein the logout-url property is specified. Remove or comment out the first one, and try again, or add the logout-url property to the first one (and remove or comment out the second), and see what happens.

Multiple <http> tags with same authentication manager in Spring Security 3.1

I am using Spring Security 3.1.2
This version allows multiple "http" tags.
I have an application that has two separate login pages, one for user and another for admin. Both of them will use the same authentication manager.
I have build my spring-security.xml in the following manner
<sec:http pattern="/loginForm.jsp" security="none"/>
<sec:http pattern="/loginForm2.jsp" security="none"/>
<sec:http auto-config="true">
<sec:intercept-url pattern="/login1*" access="ROLE_USER" />
<sec:form-login login-page="/loginForm.jsp" default-target-url="/login1"
authentication-failure-url="/loginForm.jsp?login_error=1" />
<sec:logout logout-success-url="/loginForm.jsp" />
</sec:http>
<sec:http auto-config="true">
<sec:intercept-url pattern="/login2*" access="ROLE_ADMIN" />
<sec:form-login login-page="/loginForm2.jsp" default-target-url="/login2"
authentication-failure-url="/loginForm2.jsp?login_error=1" />
<sec:logout logout-success-url="/loginForm2.jsp" />
</sec:http>
<sec:authentication-manager>
<sec:authentication-provider>
<sec:user-service>
<sec:user name="qwertyui" password="123456" authorities="ROLE_USER" />
<sec:user name="asdfghjk" password="123456" authorities="ROLE_USER" />
</sec:user-service>
</sec:authentication-provider>
</sec:authentication-manager>
But I am getting this error "A universal match pattern ('/**') is defined before other patterns in the filter chain, causing them to be ignored. Please check the ordering in your namespace or FilterChainProxy bean configuration"
If I omit any one of the tag, it works fine.
If you don't set the pattern attribute on your http element, your http stanza will default to /**, which is a universal match pattern.
I made this mistake myself, because I thought it was only considering the "intercept-url" elements, and none of my intercept-url elements defined a universal match pattern.
Make sure all of your http elements have a pattern attribute defined.
http tag creates security filter chain, default is /**, since you have two of with same default pattern, hence the error, Makes sense, how would spring build filter chains. its duplicate.

Spring Security Remember Me service without HttpSession

My question is similar to this one, but I can simplify it some. Basically I want to authenticate users through the remember me cookie, but I want everything on the server side to be completely stateless, i.e. never create a HttpSession. I have the following setup:
<security:http use-expressions="true" create-session="stateless" >
<security:intercept-url pattern="/index.jsp" access="hasRole('ROLE_ANONYMOUS')" />
<security:intercept-url pattern="/**" access="hasRole('ROLE_TEST')" />
<security:form-login login-page="/index.jsp" default-target-url="/home" always-use-default-target="true" authentication-failure-url="/index.jsp?login_error=1" />
<security:logout logout-success-url="/index.jsp"/>
<security:remember-me key="MY_KEY" />
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="testUser" password="testPassword" authorities="ROLE_TEST" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
I authenticate just fine with the username and password above and see the remember me cookie in my browser. That part of it is working great. However, I'm finding it is creating a session during this process. I thought the create-session="stateless" was supposed to prevent this. Am I missing something here?
After working with this more, I found out that it wasn't Spring Security that was creating the session. The index.jsp was creating a new session every time I hit it. I simply added <%# page session="false"> to the top of index.jsp, and now there are no sessions being created.

Resources