Another possible solution which I have tested and running is to implement a filter and put it in the FilterProxyChain.
Here's a sample implementation:
Code:
public class BlacklistFilter extends OncePerRequestFilter {
protected static Logger logger = Logger.getLogger("service");
private String redirectURI = "/krams/auth/login";
@Resource(name="sessionRegistry")
private SessionRegistry sessionRegistry;
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
private LogoutHandler[] handlers = new LogoutHandler[] {new SecurityContextLogoutHandler()};
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
logger.debug("Running blacklist filter");
HttpSession session = request.getSession(false);
if (session != null) {
SessionInformation info = sessionRegistry.getSessionInformation(session.getId());
if (info != null) {
Boolean bool = (Boolean) session.getAttribute("hasLoggedIn");
if (bool != null) {
logger.debug("Second time");
logger.debug(request.getRequestURI());
if (request.getRequestURI().equals("/spring-security-prelogin/krams/main/solo") == true) {
session.removeAttribute("hasLoggedIn");
logger.debug("Expiring session");
info.expireNow();
logger.debug("Logout");
doLogout(request, response);
logger.debug("Redirecting");
redirectStrategy.sendRedirect(request, response, redirectURI);
return;
} else {
logger.debug("Url is okay");
session.setAttribute("hasLoggedIn", new Boolean(true));
info.refreshLastRequest();
}
} else {
logger.debug("First time");
session.setAttribute("hasLoggedIn", new Boolean(true));
info.refreshLastRequest();
}
} else {
logger.debug("Info is null");
}
} else {
logger.debug("Session is null");
}
// User details are not empty
logger.debug("Continue with remaining filters");
filterChain.doFilter(request, response);
}
private void doLogout(HttpServletRequest request, HttpServletResponse response) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
for (int i = 0; i < handlers.length; i++) {
handlers[i].logout(request, response, auth);
}
}
public String getRedirectURI() {
return redirectURI;
}
public void setRedirectURI(String redirectURI) {
this.redirectURI = redirectURI;
}
}
This was originally inside a subclass of ConcurrentSessionFilter. But I decided to move the code as a separate filter so as not to pollute the ConcurrentSessionFilter.
Then inside the http tag, you include a custom-filter tag:
Code:
<security:custom-filter ref="blacklistFilter" after="CONCURRENT_SESSION_FILTER"/>
With a reference to a bean:
Code:
<bean id="blacklistFilter" class="org.krams.tutorial.filter.BlacklistFilter" />
What's the catch? If you create a new tab and enter the main URL, you will be forced to the login-page. If you refresh the page, same behavior. If you close and open the browser, same behavior.
It's a catch because it's too restrictive. Of course the code above can still be improved since it's just a quick and dirty implementation
I'm gonna make a guide for this just to show how it's done. Or maybe someone out there may find this useful.