I have a spring web application and I did user authentication using Spring security.
Everything works well. Log in and Log out works perfect!
Now, I want to implement in order to log out automatically. For example, if user has a window opened for about 30 minutes and do nothing (Sessions expired for instance) system should log out automatically. How can I implement this?
It might be implemented by client side (I send requests every 1 minutes and check if session is ended). But can't I do this automatically from Spring?
I have this config:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/admin**" />
<access-denied-handler error-page="/403" />
<form-login login-page="/login"
default-target-url="/admin"
authentication-failure-url="/login?error"
username-parameter="NAME"
password-parameter="PASSWORD" />
<logout invalidate-session="true"
logout-success-url="/login?logout"/>
</http>
and in web.xml
<session-config>
<session-timeout>1</session-timeout>
</session-config>
after 1 minute, I see that session was destroyed. kill the session after 1 minute. but page was not redirected to /login?logout
Spring security provides following 2 options: Perform the POST logout (this is default and recommended.) Perform the GET logout by disabling CSRF feature.
Spring Security Session Timeout In the case of Tomcat we can set the session timeout by configuring the maxInactiveInterval attribute on the manager element in server. xml or using the session-timeout element in web. xml. Note that the first option will affect every app that's deployed to the Tomcat instance.
logout/> </http> The element enables the default logout mechanism – which is configured to use the following logout url: /logout which used to be /j_spring_security_logout before Spring Security 4.
Solution. Review the existing Spring Security's authentication class, the “locked” feature is already implemented. To enable the limit login attempts, you need to set the UserDetails. isAccountNonLocked to false.
Either it may be spring-security, spring-mvc or servlet, auto logout is not possible without perfect client side logic.
Considering application will have both type of request
Auto logout needs very calculated logic. Presenting my autologout functionality implementation with following
1. Include auto logout script in required JSP pages as given below.
....
</body>
<jsp:include page="../template/autologout-script.jsp"></jsp:include>
</html>
2. Create a JSP page, autologout-script.jsp and add below code. Note: No editing/configuring is required
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<script>
$(document).ready(function()
{
var timeOutTimeInSeconds = ${ timeOutTimeInSeconds };
var showTimerTimeInSeconds= ${ showTimerTimeInSeconds };
var sessionCheckIntervalId = setInterval(redirectToLoginPage, timeOutTimeInSeconds * 1000);
var timerDisplayIntervalId = setInterval(showTimer, (timeOutTimeInSeconds - showTimerTimeInSeconds) * 1000);
var badgeTimerId;
window.localStorage.setItem("AjaxRequestFired", new Date());
function redirectToLoginPage(){
//location.href = '<c:url value="/" />'+'${loginPageUrl}';
window.location.reload();
}
$(document).ajaxComplete(function () {
resetTimer();
});
$(window).bind('storage', function (e) {
if(e.originalEvent.key == "AjaxRequestFired"){
console.log("Request sent from another tab, hence resetting timer")
resetTimer();
}
});
function resetTimer()
{
showTimerTimeInSeconds= ${ showTimerTimeInSeconds };
console.log("timeOutTimeInSeconds : "+timeOutTimeInSeconds)
window.localStorage.setItem("AjaxRequestFired", new Date());
window.clearInterval(sessionCheckIntervalId);
sessionCheckIntervalId = setInterval(redirectToLoginPage, timeOutTimeInSeconds * 1000);
window.clearInterval(timerDisplayIntervalId);
timerDisplayIntervalId = setInterval(showTimer, (timeOutTimeInSeconds - showTimerTimeInSeconds) * 1000);
hideTimer();
}
function showTimer()
{
$('#sessionTimeRemaining').show();
$('#sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
window.clearInterval(timerDisplayIntervalId);
badgeTimerId = setInterval(function(){
$('#sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
}, 1000);
}
function hideTimer()
{
window.clearInterval(badgeTimerId);
$('#sessionTimeRemaining').hide();
}
});
</script>
3. Configure session attributes to configuring timeout setting Note: Configure this after session creation. You can implement HttpSessionListener sessionCreated method and set the following configuration as per your requirement.
session.setMaxInactiveInterval(300);
session.setAttribute("timeOutTimeInSeconds", 300);
session.setAttribute("showTimerTimeInSeconds", 30);
4. Add below html for displaying timer.
Note: it can be moved to autologout-script template page if you are good at CSS. Hence you can avoid to add this in each and every page.
Include bootstrap or add your custom css.
<span class="badge badge-primary" title="click to keep session alive" id="sessionTimeRemaining"
onclick="ajaxSessionRefresh()" style="display:none;">
<i class="badge badge-danger" id="sessionTimeRemainingBadge" style="float:left">30</i>
<small>Refresh</small>
<i class="glyphicon glyphicon-refresh"></i>
</span>
That is all about a simple auto logout implementation.
You can download working example from my github repository
Autologout using simple servlet example
Autologout using spring-security java configuration example
Autologout using spring-security xml configuration example
Limitations/Improvements required
1. If maximum allowed session is one, if session is taken from another system, AJAX request will fail. It needs to be handled to redirect to login page.
2. Use ajaxStart() instead of ajaxComplete() to have exact sync of idleTime values between server and browser.
Requirements
1. Jquery
response.setHeader("Refresh", "60; URL=login.jsp");
<meta http-equiv="refresh" content="60; url=login.jsp">
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With