Only Allow Login With Spring Security For Users With Certain Roles - spring

I have a login page where I want to permit everyone to access the login.jsp. For example,
<intercept-url pattern="/login.jsp" access="permitAll()" />
But I only want to allow access to users with say ROLE_ADMIN. A user with ROLE_USER may be able to successfully authenticate, but they should be redirected back to the login.jsp. What would be the best way to achieve this?

Setting the access-denied-page on <http> to the login page, and protecting URLs properly should have the desired effect.
<security:http use-expressions="true" access-denied-page="/login">
<security:form-login
login-page="/login"
default-target-url="/page/for/admins"
authentication-failure-url="/login?error=true"/>
<security:intercept-url pattern="/login.jsp" access="permitAll()" />
<security:intercept-url pattern="/page/for/admins" access="hasRole('ROLE_ADMIN')"/>
</security:http>
The user with ROLE_USER will be forwarded back to the login page right after logging in. It's not a pleasant user experience though...

Related

redirect to requested page after login using spring

This is my spring-security.xml
<http auto-config="true" path-type="ant">
<intercept-url pattern="/myaccount.html*" access="ROLE_CUSTOMER"/>
<intercept-url pattern="/viewpage.html*" access="ROLE_CUSTOMER"/>
<form-login login-page="/login.html"
authentication-success-handler-ref="ssoAuthenticationSuccessHandler"
login-processing-url="/j_security_check" default-target-url="/login.html"
authentication-failure-handler-ref="authenticationFailureHandler"/>
<logout invalidate-session="true" success-handler-ref="ssoLogoutHandler" delete-cookies="JSESSIONID,loggedIn,_bt,slc_f,slc_t,_px_i,attempt_auto_login"/>
<session-management session-fixation-protection="none"/>
</http>
If user access some URL I want to intercept him to login. After it needs to be redirected to the original requested page by user.
Above xml helps me to intercept when user access viewpage.html but after login success it is not taking me to viewpage.html. Instead it takes me to myaccount.html always.
SavedRequestAwareAuthenticationSuccessHandler is used as a default implementation class for AuthenticationSuccessHandler.
This should work as you expect.
I'm not sure what authentication-success-handler-ref="ssoAuthenticationSuccessHandler" is suppose to do, but try looking in to SavedRequestAwareAuthenticationSuccessHandler and see if you can get any clue.

Spring Security 3.2.0 Anonymous and Single Sign On - user remains anonymous

We have an application implemented with Spring Security 3.20 and CAS 3.5. Everything is working fine expect for the anonymous portion. If someone has logged into CAS, we would like them to show up in the application with their logged in username, but instead they show up as anonymousUser. This is only on pages that allow both anonymous or a logged in user. If they explicitly go to a page requiring a role, then the SSO on kicks in and they show up as whatever the logged in user is. What do we need to configure so that they show up as the logged in user without forcing them to go to a secure page (or is that the only way)?
Our configuration is as follows:
<http auto-config="true" entry-point-ref="casEntryPoint" use-expressions="true">
<intercept-url pattern="/canary.html" access="permitAll" />
<intercept-url pattern="/test.html" access="hasRole('ADM')" />
<intercept-url pattern="/testAnon.html" access="hasRole('SEC') or isAnonymous()" />
<intercept-url pattern="/policySelect.html" access="hasRole('ADM')" />
<intercept-url pattern="/**" access="hasRole('SEC') or isAnonymous()" />
<custom-filter position="CAS_FILTER" ref="casFilter" />
<logout logout-success-url="/cas-logout.jsp"/>
<custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER"/>
<custom-filter ref="singleLogoutFilter" before="CAS_FILTER"/>
<access-denied-handler error-page="/WEB-INF/jsp/403.jsp"/>
</http>
If someone is logged into CAS and goes to testAnon.html, they still show up and anonymous until they go to another page like test.html that requires the role of ADM. After that they are logged in and stay that way on all pages.

Is it possible to use HTTPS only for login in Spring security?

My requirement is to secure only the login page to protect user credentials. After successful login, the user can access to the restricted pages but in http mode.
It is a requirement because of SSL overload. Users need to access to protected pages which contains a lot of data.
I would like to know whether it is possible to do although it isn't as secure as maintain https context.
This is my config:
<security:http auto-config="true">
<security:intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="https"/>
<security:intercept-url pattern="/welcome*" access="ROLE_USER, ROLE_ADMIN" />
<security:form-login login-page="/login" authentication-failure-handler-ref="customAuthenticationFailureHandler" default-target-url="/welcome" />
<security:access-denied-handler ref="openIdAuthFailureHandler"/>
</security:http>
If I try to set /login as https, everything is in https mode. How can I manage to do that?
Edit:
As s.kwiotek suggested I added requires-channel="http" to the other url patterns:
<security:http auto-config="true">
<security:intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="https"/>
<security:intercept-url pattern="/welcome*" access="ROLE_USER, ROLE_ADMIN" requires-channel="http"/>
<security:intercept-url pattern="/user/*" access="ROLE_USER, ROLE_ADMIN" requires-channel="http" />
<security:intercept-url pattern="/rest/*" access="ROLE_USER, ROLE_ADMIN" requires-channel="http" />
<security:intercept-url pattern="/admin/*" access="ROLE_ADMIN" requires-channel="http" />
<security:session-management session-fixation-protection="none"/>
<security:port-mappings>
<security:port-mapping http="8080" https="8443"/>
</security:port-mappings>
<security:form-login login-page="/login" authentication-failure-handler-ref="customAuthenticationFailureHandler" always-use-default-target="true" default-target-url="/user/home" />
<security:logout logout-success-url="/" />
<security:access-denied-handler ref="openIdAuthFailureHandler"/>
</security:http>
I added the session-fixation-protection="none" because If I only include requires-channel="http" it doesn't go further from the login. I try to log in but I come back to the login.
If I add the session-fixation-protection it goes to the user's home but at the second login attempt. When you access to /myapp/login two jsessionid are created:
JSESSIONID=5B37413F33DF0AA45F31D711754C3704; path=/myapp; domain=localhost
JSESSIONID=658F9F8669AF6B296A77D448C1A64B71; path=/myapp/; domain=localhost; HttpOnly
Then I try to log in and I come back to the log in but the url is different:
https://myapp/login;jsessionid=C1EC352C42D6AC379DB1B65A9295E8A1
When the jsessionid is in the URL, I try to log in and I'm successfully redirected to the users'home (/user/home). If I remove the session-fixation-protection, the jessesionid is in the URL but I'm not successfully redirected to the user's home.
I don't know who creates the two first jsessionid and how to explain this behaviour. The only thing I want to do is to secure the login by ssl and then access by http.
(This should have been a comment. But my account is limited in reputation.)
You may want to reconsider allowing access to the restricted pages in http mode.
According to http://www.troyhunt.com/2011/11/owasp-top-10-for-net-developers-part-9.html,
Many people think of TLS as purely a means of encrypting sensitive user data in transit. For example, you’ll often see login forms posting credentials over HTTPS then sending the authenticated user back to HTTP for the remainder of their session. The thinking is that once the password has been successfully protected, TLS no longer has a role to play. The example above shows that entire authenticated sessions need to be protected, not just the credentials in transit. This is a lesson taught by Firesheep last year and is arguably the catalyst for Facebook implementing the option of using TLS across authenticated sessions.
Try for Example:
<security:intercept-url pattern="/**" access="ROLE_USER" requires-channel="http"/>

SpringSecurity do not forward to https

Dear All,
We have added Spring Security for our web application. Login url seems like this
https://www.xyz.com/app/login.do
after login it should redirect to other urls with same https protocol. Right now SpringSecurity redirect us to other urls but with http not https.
Please tell us any specific settings are needed.
Thanks,
Op
Within your spring security definitions, inside your intercept-url tag you need to add requires-channel="https"
For example:
<sec:intercept-url pattern="/login.jsp*" requires-channel="https" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<sec:intercept-url pattern="/j_spring_security_check*" requires-channel="https" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<sec:intercept-url pattern="/**" requires-channel="https" access="IS_AUTHENTICATED_FULLY"/>

Unexpected redirect to login page after successful login

I'm using Spring to handle security in my JSF application. I have a login page at /login and I've configured Spring like this:
<http authentication-manager-ref="authenticationManager">
<intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/admin" access="ROLE_ADMIN" />
<intercept-url pattern="/javax.faces.resource/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/**" access="ROLE_ADMIN,ROLE_USER" />
<form-login login-page="/login" authentication-failure-url="/login" />
<logout logout-url="/logout" />
</http>
I want the admin page at /admin to be available only for users with the ROLE_ADMIN role. Users with ROLE_ADMIN or ROLE_USER may access pages starting from the application root.
When I login with a user having either role I see the page you should see after login. However, whatever my next action may be I get redirected to /login like I'm not logged in. Can someone please explain this as I'm trying to get this thing to work for a day now. I've been reading the Spring 3.1.x documentation but it doesn't give me a clue about how to solve the problem. I'm running Spring 3.1.1.Release by the way.
Extra bonus info: the page you should see after login has an element that should only render if the user had ROLE_ADIN. I can see that element after login. The problems began when I implemented PrettyFaces. I've searched the web for common problems and only came up with that the PrettyFaces filter should appear after the Spring security filter. This is the case so it should work right?
UPDATE: I've updated my config to use expressions. However the problem still exists.
<http authentication-manager-ref="authenticationManager" use-expressions="true">
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/admin" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/javax.faces.resource/**" access="permitAll" />
<intercept-url pattern="/**" access="hasAnyRole('ROLE_ADMIN','ROLE_USER')" />
<form-login login-page="/login" authentication-failure-url="/login" />
<logout logout-url="/logout" />
</http>
Output in Firebug's console just after login (the page tries an AJAX call):
First, always debug Spring Security when having problems (add log4j.logger.org.springframework.security=DEBUG).
Second, I think that you wanted hasAnyRole:
<intercept-url pattern="/**" access="hasAnyRole(ROLE_ADMIN,ROLE_USER)" />
plus add use-expressions="true" to http:
<http authentication-manager-ref="authenticationManager" use-expressions="true">
to allow ROLE_ADMIN xor ROLE_USER users to access page. In your current config user must have both roles to access /**.

Resources