How To Automatically Log Out Using Spring Security

I have a spring web application and have authenticated the user using spring security.

Everything works well. Entry and exit are stopped!

Now I want to implement in order to automatically log out. For example, if a user opens a window for about 30 minutes and nothing is done (sessions have expired, for example), the system should log out automatically. How can i implement this?

It can be implemented on the client side (I send requests every 1 minute and check if the session is completed). But can I do this automatically from Spring?

I have this configuration:

<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 the session was destroyed. kill the session after 1 minute. but the page was not redirected to / login? logout

+11
source share
5 answers

How to use security configuration. Hope the below config: will work.

applicationContext.xml

  --namespace-> xmlns:security="http://www.springframework.org/schema/security" <security:logout invalidate-session="true" success-handler-ref="Logout" logout-url="/logout.html" /> </security:http> 

web.xml

  <session-config> <session-timeout> 30 </session-timeout> </session-config> 

And to them, you need to write your own, because success-handler-ref = "Exit" is a custom exit handler:
@Component exit

 public class Logout extends SimpleUrlLogoutSuccessHandler { @Override public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { if (authentication != null) { // do something } setDefaultTargetUrl("/login"); super.onLogoutSuccess(request, response, authentication); } } 
+5
source

You can use the global timeout value by placing it in your web.xml:

 <session-config> <session-timeout>30</session-timeout> </session-config> 
+1
source

Here is the tutorial that I used. There is java script and server side code. The server will calculate when the session has expired and will send it as a cookie. Then the java script will be checked every 10 seconds, if it expired, if so, there will be window.close (). http://www.javaworld.com/article/2073234/tracking-session-expiration-in-browser.html

This is how I implemented it

SessionTimeout.js

 /** * Monitor the session timeout cookie from Apache and log the user out when expired */ "use strict"; var jQuery = require("jquery").noConflict(); var jsCookie = require("js-cookie"); module.exports.registerListener = function() { calcOffset(); checkSession(); }; /** * We can't assume the server time and client time are the same * so lets calcuate the difference */ function calcOffset() { var serverTime = jsCookie.get('serverTime'); serverTime = serverTime==null ? null : Math.abs(serverTime); var clientTimeOffset = (new Date()).getTime() - serverTime; jsCookie.set('clientTimeOffset', clientTimeOffset); } /** * Check the sessionExpiry cookie and see if we should send the user to / */ function checkSession() { var sessionExpiry = Math.abs(jsCookie.get('sessionExpiry')); var timeOffset = Math.abs(jsCookie.get('clientTimeOffset')); var localTime = (new Date()).getTime(); if(!sessionExpiry){ window.console.log("Unknown session sessionExpiry"); return; } if (localTime - timeOffset > (sessionExpiry+15000)) { // 15 extra seconds to make sure window.location = "/login"; jsCookie.remove('sessionExpiry'); } else { setTimeout('checkSession()', 10000); } window.console.log("Session expires in " + ((sessionExpiry+15000) - localTime - timeOffset) + "ms"); } window.checkSession = checkSession; //Used for recalling via setTimeout 

SessionTimeoutCookieFilter.java

 public class SessionTimeoutCookieFilter implements Filter { private static final Logger LOG = LoggerFactory.getLogger(SessionTimeoutCookieFilter.class); @Override public void init(FilterConfig config) throws ServletException { LOG.info("Initialization SessionTimeoutCookieFilter"); } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse httpResp = (HttpServletResponse) resp; HttpServletRequest httpReq = (HttpServletRequest) req; long currTime = System.currentTimeMillis(); String expiryTime = Long.toString(currTime + httpReq.getSession().getMaxInactiveInterval() * 1000); Cookie cookie = new Cookie("serverTime", Long.toString(currTime)); cookie.setPath("/"); httpResp.addCookie(cookie); if (httpReq.getRemoteUser() != null) { cookie = new Cookie("sessionExpiry", expiryTime); } cookie.setPath("/"); httpResp.addCookie(cookie); filterChain.doFilter(req, resp); } 

Add filter

 public class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { ... @Override protected Filter[] getServletFilters() { return new Filter[]{new SessionTimeoutCookieFilter()}; } } 
0
source

To redirect to the login page after the session expires, add the "invalid-session-url" tag to the "session management" bean in the security context:

 <session-management invalid-session-url="/error-login"> .... </session-management> 

In my case, I am redirected to the error registration page where the error message is displayed, and I can re-login. Keep in mind that when the session expires, you will not be automatically redirected. You need to click on any part of your page and trigger a redirect.

0
source

It can be Spring-Security, Spring-MVC or a servlet, automatic failure is impossible without perfect logic on the client side.
The application in question will have both types of requests

  • Ajax and
  • form submission / page reload

Automatically logging out requires very sophisticated logic. Introducing my autologout function implementation with the following

Benefits.


1. No additional calls / requests are used to achieve this. taking into account the impact on productivity, if more than 10,000 active users and additional calls to achieve automatic exit.
2. Single line configuration using a tag.
3. It works flawlessly, even if the user opens several tabs or multiple windows.
4. He informs you that up to 30 seconds of the session is invalid, so if you filled out the form and did not submit it, you can keep the session alive (extend the session with one click of the mouse). Thus, the user is less likely to lose unsaved data.


Usage 1. Turn on the automatic logoff script on the required JSP pages as follows.

  .... </body> <jsp:include page="../template/autologout-script.jsp"></jsp:include> </html> 

2. Create a JSP page, autologout-script.jsp and add the code below. Note. Editing / customization is not 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 configure timeouts. Note. Configure this after creating the session. You can implement the sessionCreated HttpSessionListener method and set the following configuration according to your requirements.

 session.setMaxInactiveInterval(300); session.setAttribute("timeOutTimeInSeconds", 300); session.setAttribute("showTimerTimeInSeconds", 30); 

4. Add the HTML below to display the timer.
Note: you can move it to the autolog script page if you are good at CSS. Therefore, you can avoid adding this to every page.
Turn on the loader or add your own 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> &nbsp; <small>Refresh</small> <i class="glyphicon glyphicon-refresh"></i> </span> 

enter image description here

It's all about the simple implementation of automatic logout. You can download a working example from my github repository
Autologout using a simple servlet example
Autologout using the Spring-Security Java configuration example
Autologout using Spring-Security XML configuration example

Explained Logic


Case 1: when loading a page
Here the logic is simple, when loading the page, set the interval equation timer to maxInactiveInterval. after a timeout redirect to the login page.
Case 2: Track AJAX Calls
Now when looking at AJAX requests, you can use .ajaxStart () or .ajaxComplete () jquery callbacks so that when you run any ajax request you can reset the interval.
Case 3: tracking the activity of multiple tabs / windows
Intertab communication is done to synchronize the state of each tab. Used localStorage when changing the event.

Constraints / improvements required
1. If the maximum allowed session is equal to one, if the session is taken from another system, the AJAX request will not be executed. This needs to be processed in order to redirect to the login page.
2. Use ajaxStart () instead of ajaxComplete () to precisely synchronize idleTime values ​​between the server and browser.

Requirements
1. jquery

Comparison of alternatives to the current implementation


1. Setting the header update in the http response. (Does not work for AJAX requests)

 response.setHeader("Refresh", "60; URL=login.jsp"); 
  1. Customizing meta meta tag in HTML (not working for AJAX requests)
 <meta http-equiv="refresh" content="60; url=login.jsp"> 
  1. Configure Activity Checks Supports a session by re-invoking an AJAX. Monitors downtime and sends an exit request after a timeout.
    No doubt it's good with simple logic. But I just want to draw my observations.
    • Performance impact if 2 requests are executed per minute to maintain session activity and 50,000 active users. 100,000 requests per minute.
    • Relationship between tabs If two tabs are open, one tab receives activity, but the other tab does not receive activity, this tab launches a request to exit the system and invalidates the session, even if activity is present on another tab. (But can be processed)
    • Force Logout Approach This client dominates the server to terminate the session.
0
source

Source: https://habr.com/ru/post/1210385/


All Articles