/* * ****************************************************************************** * * Cloud Foundry * * Copyright (c) [2009-2015] Pivotal Software, Inc. All Rights Reserved. * * * * This product is licensed to you under the Apache License, Version 2.0 (the "License"). * * You may not use this product except in compliance with the License. * * * * This product includes a number of subcomponents with * * separate copyright notices and license terms. Your use of these * * subcomponents is subject to the terms and conditions of the * * subcomponent's license, as noted in the LICENSE file. * ****************************************************************************** */ package org.cloudfoundry.identity.uaa.authentication; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.cloudfoundry.identity.uaa.constants.OriginKeys; import org.cloudfoundry.identity.uaa.user.UaaUser; import org.cloudfoundry.identity.uaa.user.UaaUserDatabase; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.web.RedirectStrategy; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.util.Date; public class SessionResetFilter extends OncePerRequestFilter { private static Log logger = LogFactory.getLog(SessionResetFilter.class); private final RedirectStrategy strategy; private final String redirectUrl; private final UaaUserDatabase userDatabase; public SessionResetFilter(RedirectStrategy strategy, String redirectUrl, UaaUserDatabase userDatabase) { this.strategy = strategy; this.redirectUrl = redirectUrl; this.userDatabase = userDatabase; } public String getRedirectUrl() { return redirectUrl; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { SecurityContext context = SecurityContextHolder.getContext(); if (context!=null && context.getAuthentication()!=null && context.getAuthentication() instanceof UaaAuthentication) { UaaAuthentication authentication = (UaaAuthentication)context.getAuthentication(); if (authentication.isAuthenticated() && OriginKeys.UAA.equals(authentication.getPrincipal().getOrigin()) && null != request.getSession(false)) { boolean redirect = false; String userId = authentication.getPrincipal().getId(); try { logger.debug("Evaluating user-id for session reset:"+userId); UaaUser user = userDatabase.retrieveUserById(userId); Date lastModified; if ((lastModified = user.getPasswordLastModified()) != null) { long lastAuthTime = authentication.getAuthenticatedTime(); long passwordModTime = lastModified.getTime(); //if the password has changed after authentication time if (hasPasswordChangedAfterAuthentication(lastAuthTime, passwordModTime)) { logger.debug(String.format("Resetting user session for user ID: %s Auth Time: %s Password Change Time: %s",userId, lastAuthTime, passwordModTime)); redirect = true; } } } catch (UsernameNotFoundException x) { logger.info("Authenticated user ["+userId+"] was not found in DB."); redirect = true; } if (redirect) { handleRedirect(request, response); return; } } } filterChain.doFilter(request,response); } protected boolean hasPasswordChangedAfterAuthentication(long lastAuthTime, long passwordModTime) { return passwordModTime > lastAuthTime; } protected void handleRedirect(HttpServletRequest request, HttpServletResponse response) throws IOException { HttpSession session = request.getSession(false); if (session!=null) { session.invalidate(); } strategy.sendRedirect(request, response, getRedirectUrl()); } }