Spring security logout after session timeout - spring

I'm having a problem logging out of the application after the session times out. I've configured the logout url:
<security:logout logout-url="/logout" logout-success-url="/" delete-cookies="JESSIONID"/>
and I have the logout form:
<form action="#" th:action="#{/logout}" method="POST">
<input type="submit" th:value="#{btn.logout}"/>
</form>
The form tag adds the csrf parameter and logging out works well as long as the session is still active. But if I log in the application, leave it open long enough for the session to expire and then hit the logout button I get the error:
HTTP Status 405 - Request method 'POST' not supported
I'd still like to keep the csrf validation and make it work as a POST request.

I found the solution in the documentation:
In your spring security configuration you have to add the following line:
<session-management invalid-session-url="/login" />
An example:
<form-login
login-page="/login"
default-target-url="/"
authentication-failure-url="/login?error"
username-parameter="username"
password-parameter="password" />
<session-management invalid-session-url="/login" />
<form-login login-processing-url="/login" login-page="/login"/>
<logout logout-success-url="/" logout-url="/logout"/>
I hope it will help you.

Set the Refresh HTTP header for just after session expiry. This will cause the page to reload itself just after the session expires, essentially logging you out.

It is due to the fact that when session expires, the csrf token with the login form is no longer valid. And making a post request with invalid csrf token causes spring to give a 405 i.e. Method Not Supported Error.
Solution:
Add the following configuration in Http Security Configuration.
For Java Config:
.and().sessionManagement().invalidSessionUrl("/login")
For XML Config:
> <session-management invalid-session-url="/login" />

Related

Spring Security cannot request URL with jessionid

I am developing a web application using Spring 5.3.20, Spring Security 5.7.1 and Tomcat 9.0.62.
Here is my Spring Security settings:
<form-login login-page="/home" />
<logout logout-url="/logout"
logout-success-url="/login?logout"
delete-cookies="JSESSIONID"/>
<session-management invalid-session-url="/main?timeout" session-authentication-error-url="/main?error"
session-fixation-protection="newSession">
<concurrency-control max-sessions="1" expired-url="/mail"
error-if-maximum-exceeded="true" session-registry-alias="sessionRegistry" />
</session-management>
The problem is when user logged out, the JSESSIONID cookies is deleted and the URL Rewriting kicked in.
As as result, the CSS, JS URLs become something like this.
http://localhost:8080/bookstore/resources/css/bootstrap.min-7184d3edc008c1890deb0a71e4348267.css;jsessionid=5052769FD8FEB8D2901C8CCB2B6A0C66
http://localhost:8080/bookstore/resources/js/jquery-1.12.3.min-2b6294333db8eeb65bc7717144357d23.js;jsessionid=5052769FD8FEB8D2901C8CCB2B6A0C66
The JESSIONID and semicolon are appended to the URLs which is a problem because according to those links below, the Spring Security will reject URLs that contain semicolons.
Spring getting The request was rejected because the URL contained a potentially malicious String ";"
https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/firewall/StrictHttpFirewall.html
There are two ways to solve this problem.
Not deleting the JSESSIONID cookies when logged out by removing delete-cookies="JSESSIONID"
<logout logout-url="/logout"
logout-success-url="/login?logout"/>
Forcing Spring Security to allow semicolons in URL by using setAllowSemicolon(true)
But from best security practices perspectives I think both of those solution above are not really good.
Can you guys elaborate in real world web application how people handle such a situation?

Redirect to view-state afte login success

I'm using for first time spring security (3.2.0.RELEASE) and spring webflow (2.4.0.RC1).
I have a webflow where there is a view-stat which needs a user authenticated:
<view-state id="finish" model="order">
<secured attributes="ROLE_USER" />
<on-render>
<render fragments="body" />
</on-render>
</view-state>
If user is not already authenticated is redirected to a login page. I'm wondering if would be possible: user insert his credentials into login page and if he has success, redirect him to "finish" view-state again with all information of flow.
It's posible?
Yes it is possible. In spring-security.xml specify the flow URL in "default-target-url" attribute.
If the URL to your flow is something like screen/finish, then the configuration would be like below
<http auto-config="true" >
<form-login login-page="/login.jsp"
login-processing-url="/j_spring_security_check"
authentication-failure-url="/login.jsp?error=t"
default-target-url="screen/finish"
always-use-default-target="true" />
<!--other configurations -->
</http>

how to delete remember me cookie in spring security

I was wondering how to the remove the remember me cookie when using spring remember me services.
I am using the default remember me cookie name
I came across the following documentation in spring to delete the JSESSION.
<http>
<logout delete-cookies="JSESSIONID" />
</http>
But is it possible to do something like below to delete the remember me cookie as well
I don't have a logout controller and i have the following configuration in the spring xml.
<http use-expressions="true">
<!-- Authentication policy -->
<form-login login-page="/signin" login-processing-url="/signin/authenticate" authentication-failure-url="/signin?param.error=bad_credentials" />
<logout logout-url="/signout" delete-cookies="JSESSIONID" />
....................
I don't think you have to manually delete the remember-me cookie. The AbstractRememberMeServices implements the LogoutHandler interface, so it will receive a call-back from the LogoutFilter, and makes sure the remember-me cookie is cancelled on logout.

Why do I get an invalid-session redirect after a Spring Security logout?

I have a Spring MVC project which uses Spring Security. I am wondering how j_spring_security_logout works. I have a logout link defined in a view like this:
Logout
In my spring-security.xml I have defined this:
<form-login login-page="/login" default-target-url="/wellcome" authentication-failure-url="/loginfailed" />
<logout logout-success-url="/logout" logout-url="/j_spring_security_logout" />
<session-management invalid-session-url="/invalidsession" />
I expected that clicking logout should redirect me to /logout, but instead I get redirected to the invalid-session-url, namely /invalidsession. The logout-success-url is ignored.
However when I delete session-management, logging out does indeed redirect me to /logout.
This is explained in the Spring Security reference manual.
You can't really use the session-expiry facility unless the session cookie is deleted when you log out.
Use just this one and it should work (without logout-url):
<logout logout-success-url="/logout" />
I think you may experience problems by using both logout and session management invalid session url because once you've logged out your session is no longer valid.
Update per your additional question, how about this :
<security:logout logout-success-url="/logout?displayLogout=1" />
<security:session-management invalid-session-url="/logout?displayLogout=0" />
And then in your view :
<c:if test="${param.displayLogout == 0}">
<h2>Your session has timed out.</h2>
</c:if>
Update #2, just tried it locally, when you logout your session is invalid and you get redirected to invalid-session-url location you specified in the session-management configuration.
Really interested in the solution now.

Spring Security: Redirect to invalid-session-url instead of logout-success-url on successful logout

I have implemented a login-logout system with Spring Security 3.0.2, everything is fine but for this one thing: after I added a session-management tag with invalid-session-url attribute, on logout Spring would always redirect me on the invalid-session-url instead of the logout-success-url (which it correctly did before).
Is there a way to avoid this behaviour?
This is my configuration:
<http use-expressions="true" auto-config="true">
[...some intercept-url's...]
<form-login login-page="/login" authentication-failure-url="/login?error=true"
login-processing-url="/login-submit" default-target-url="/home"
always-use-default-target="true" />
<logout logout-success-url="/home?logout=true" logout-url="/login-logout" />
<session-management invalid-session-url="/home?invalid=true" />
</http>
Thanks a lot.
By default, the logout process will first invalidate the session, hence triggering the session management to redirect to the invalid session page. By specifying invalidate-session="false" will fix this behavior.
<sec:logout logout-success-url="/logout" invalidate-session="false"
delete-cookies="JSESSIONID" />
Do not confuse the logout-url attribute in the logout tag with the invalid-session-url attribute from session-management.
The latter is the URL to execute the action of logging out while the former is the URL being forwarded to upon a logout action.
To put it in other words, when creating a logout button, the URL for that button would be the logout-url value.
Now when the logout is done, spring security, be default, will render the main application's root app path, i.e.: http://yourserver:yourport/yourwebapp/. This path is overridden by invalid-session-url. So upon logout, you will be forwarded there.
To sum up, if you don't want the behavior you're asking for, then do not use invalid-session-url attribute.
Hope that helps.

Resources