Uploaded image for project: 'Spring Security'
  1. Spring Security
  2. SEC-2091

CookieClearingLogoutHandler doesn't work correctly when servlet container adds an extra '/' at the end of the contextPath

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: 3.1.1, 3.1.2
    • Fix Version/s: None
    • Component/s: Web
    • Labels:
      None
    • Environment:
      tomcat-catalina 7.0.26

      Description

      ApplicationSessionCookieConfig.createSessionCookie(Context,String,boolean) method adds an '/' at the the end of the contextPath when session cookie path has a trailing '/'.

        if (context.getSessionCookiePathUsesTrailingSlash()) {
           // Handle special case of ROOT context where cookies require a path of
           // '/' but the servlet spec uses an empty string
           // Also ensure the cookies for a context with a path of /foo don't get
           // sent for requests with a path of /foobar
           if (!contextPath.endsWith("/")) {
               contextPath = contextPath + "/";
        }
      

      In this case, CookieClearingLogoutHandler doesn't set the correct path to the cookie.

        String cookiePath = request.getContextPath();
        if(!StringUtils.hasLength(cookiePath)) {
          cookiePath = "/";
        }
        cookie.setPath(cookiePath);
      

      A workaround for this issue is to disable sessionCookiePathUsesTrailingSlash attribute at the tomcat context as it is described at http://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Defining_a_context

      or by implementing a custom CookieClearingLogoutHandler

      import java.util.Arrays;
      import java.util.List;
      
      import javax.servlet.http.Cookie;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      
      import org.springframework.security.core.Authentication;
      import org.springframework.security.web.authentication.logout.LogoutHandler;
      import org.springframework.util.Assert;
      import org.springframework.util.StringUtils;
      
      
      public final class CustomCookieClearingLogoutHandler implements LogoutHandler {
          private final List<String> cookiesToClear;
      
          public CustomCookieClearingLogoutHandler(String... cookiesToClear) {
              Assert.notNull(cookiesToClear, "List of cookies cannot be null");
              this.cookiesToClear = Arrays.asList(cookiesToClear);
          }
      
          public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
              for (String cookieName : cookiesToClear) {
                  Cookie cookie = new Cookie(cookieName, null);
                  String cookiePath = request.getContextPath();
                  if(!StringUtils.hasLength(cookiePath)) {
                      cookiePath = "/";
                  }else if (cookiePath.startsWith("/")){
                  	cookiePath += "/";
                  }
                  cookie.setPath(cookiePath);
                  cookie.setMaxAge(0);
                  response.addCookie(cookie);
              }
          }
      }
      

        Attachments

          Activity

            People

            Assignee:
            Unassigned
            Reporter:
            ithana Yannis Thanasoulas
            Votes:
            5 Vote for this issue
            Watchers:
            6 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: