|
@@ -16,36 +16,34 @@
|
|
|
package org.springframework.security.concurrent;
|
|
|
|
|
|
import org.springframework.beans.factory.InitializingBean;
|
|
|
-
|
|
|
+import org.springframework.security.ui.FilterChainOrderUtils;
|
|
|
+import org.springframework.security.ui.SpringSecurityFilter;
|
|
|
import org.springframework.util.Assert;
|
|
|
|
|
|
-import java.io.IOException;
|
|
|
-
|
|
|
-import javax.servlet.Filter;
|
|
|
import javax.servlet.FilterChain;
|
|
|
-import javax.servlet.FilterConfig;
|
|
|
import javax.servlet.ServletException;
|
|
|
-import javax.servlet.ServletRequest;
|
|
|
-import javax.servlet.ServletResponse;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
import javax.servlet.http.HttpSession;
|
|
|
+import java.io.IOException;
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * Filter required by concurrent session handling package.<p>This filter performs two functions. First, it calls
|
|
|
- * {@link org.springframework.security.concurrent.SessionRegistry#refreshLastRequest(String)} for each request. That way,
|
|
|
- * registered sessions always have a correct "last update" date/time. Second, it retrieves {@link
|
|
|
- * org.springframework.security.concurrent.SessionInformation} from the <code>SessionRegistry</code> for each request and checks
|
|
|
- * if the session has been marked as expired. If it has been marked as expired, the session is invalidated. The
|
|
|
- * invalidation of the session will also cause the request to redirect to the URL specified, and a {@link
|
|
|
- * org.springframework.security.ui.session.HttpSessionDestroyedEvent} to be published via the {@link
|
|
|
- * org.springframework.security.ui.session.HttpSessionEventPublisher} registered in <code>web.xml</code>.</p>
|
|
|
+ * Filter required by concurrent session handling package.
|
|
|
+ * <p>This filter performs two functions. First, it calls
|
|
|
+ * {@link org.springframework.security.concurrent.SessionRegistry#refreshLastRequest(String)} for each request.
|
|
|
+ * That way, registered sessions always have a correct "last update" date/time. Second, it retrieves
|
|
|
+ * {@link org.springframework.security.concurrent.SessionInformation} from the <code>SessionRegistry</code>
|
|
|
+ * for each request and checks if the session has been marked as expired.
|
|
|
+ * If it has been marked as expired, the session is invalidated. The invalidation of the session will also cause the
|
|
|
+ * request to redirect to the URL specified, and a
|
|
|
+ * {@link org.springframework.security.ui.session.HttpSessionDestroyedEvent} to be published via the
|
|
|
+ * {@link org.springframework.security.ui.session.HttpSessionEventPublisher} registered in <code>web.xml</code>.</p>
|
|
|
*
|
|
|
* @author Ben Alex
|
|
|
* @version $Id$
|
|
|
*/
|
|
|
-public class ConcurrentSessionFilter implements Filter, InitializingBean {
|
|
|
+public class ConcurrentSessionFilter extends SpringSecurityFilter implements InitializingBean {
|
|
|
//~ Instance fields ================================================================================================
|
|
|
|
|
|
private SessionRegistry sessionRegistry;
|
|
@@ -55,23 +53,12 @@ public class ConcurrentSessionFilter implements Filter, InitializingBean {
|
|
|
|
|
|
public void afterPropertiesSet() throws Exception {
|
|
|
Assert.notNull(sessionRegistry, "SessionRegistry required");
|
|
|
- Assert.hasText(expiredUrl, "ExpiredUrl required");
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Does nothing. We use IoC container lifecycle services instead.
|
|
|
- */
|
|
|
- public void destroy() {}
|
|
|
-
|
|
|
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
|
|
- throws IOException, ServletException {
|
|
|
- Assert.isInstanceOf(HttpServletRequest.class, request, "Can only process HttpServletRequest");
|
|
|
- Assert.isInstanceOf(HttpServletResponse.class, response, "Can only process HttpServletResponse");
|
|
|
+ public void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
|
|
|
+ throws IOException, ServletException {
|
|
|
|
|
|
- HttpServletRequest httpRequest = (HttpServletRequest) request;
|
|
|
- HttpServletResponse httpResponse = (HttpServletResponse) response;
|
|
|
-
|
|
|
- HttpSession session = httpRequest.getSession(false);
|
|
|
+ HttpSession session = request.getSession(false);
|
|
|
|
|
|
if (session != null) {
|
|
|
SessionInformation info = sessionRegistry.getSessionInformation(session.getId());
|
|
@@ -81,8 +68,14 @@ public class ConcurrentSessionFilter implements Filter, InitializingBean {
|
|
|
// Expired - abort processing
|
|
|
session.invalidate();
|
|
|
|
|
|
- String targetUrl = httpRequest.getContextPath() + expiredUrl;
|
|
|
- httpResponse.sendRedirect(httpResponse.encodeRedirectURL(targetUrl));
|
|
|
+ if (expiredUrl != null) {
|
|
|
+ String targetUrl = request.getContextPath() + expiredUrl;
|
|
|
+ response.sendRedirect(response.encodeRedirectURL(targetUrl));
|
|
|
+ } else {
|
|
|
+ response.getWriter().print("This session has been expired (possibly due to multiple concurrent " +
|
|
|
+ "logins being attempted as the same user).");
|
|
|
+ response.flushBuffer();
|
|
|
+ }
|
|
|
|
|
|
return;
|
|
|
} else {
|
|
@@ -95,15 +88,6 @@ public class ConcurrentSessionFilter implements Filter, InitializingBean {
|
|
|
chain.doFilter(request, response);
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Does nothing. We use IoC container lifecycle services instead.
|
|
|
- *
|
|
|
- * @param arg0 ignored
|
|
|
- *
|
|
|
- * @throws ServletException ignored
|
|
|
- */
|
|
|
- public void init(FilterConfig arg0) throws ServletException {}
|
|
|
-
|
|
|
public void setExpiredUrl(String expiredUrl) {
|
|
|
this.expiredUrl = expiredUrl;
|
|
|
}
|
|
@@ -111,4 +95,8 @@ public class ConcurrentSessionFilter implements Filter, InitializingBean {
|
|
|
public void setSessionRegistry(SessionRegistry sessionRegistry) {
|
|
|
this.sessionRegistry = sessionRegistry;
|
|
|
}
|
|
|
+
|
|
|
+ public int getOrder() {
|
|
|
+ return FilterChainOrderUtils.CONCURRENT_SESSION_FILTER_ORDER;
|
|
|
+ }
|
|
|
}
|