Spring Security
  1. Spring Security
  2. SEC-1412

Login page redisplays when used with Spring 3's ShallowEtagHeaderFilter

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 3.0.1
    • Fix Version/s: 3.0.2
    • Component/s: Core
    • Labels:
      None

      Description

      Adding ShallowEtagHeaderFilter to a web application that uses Spring Security will cause the redisplay of the Spring Security login page on the second login attempt. This was initially reported widely within the Spring Roo community and resulted in bug report ROO-579.

      The problem can be seen by:

      1. Active ShallowEtagHeaderFilter in a Spring Security application that has a normal login page
      2. Visit the home page, attempt to access a secure page, and view the login page
      3. Complete the login page, submit, and you should see the secure page (correct)
      4. Logout
      5. Attempt to access the same secure page again
      6. The login page will display (correct)
      7. Enter valid credentials and submit
      --> The login page will re-display (incorrect)
      --> What should have happened is the secure page would display, as you've now authenticated

      I have reproduced this with the Spring Security tutorial 3.0.1 web application WAR. I have made no changes to the WAR except modifying the web.xml to the following (I have included both filters for clarification of the order):

          <filter>
              <filter-name>springSecurityFilterChain</filter-name>
              <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
          </filter>
      
      	<filter>
      		<filter-name>etagFilter</filter-name>
      		<filter-class>org.springframework.web.filter.ShallowEtagHeaderFilter</filter-class>
      	</filter>
      
          <filter-mapping>
            <filter-name>springSecurityFilterChain</filter-name>
            <url-pattern>/*</url-pattern>
          </filter-mapping>
      
      	<filter-mapping>
      		<filter-name>etagFilter</filter-name>
      		<url-pattern>/*</url-pattern>
      	</filter-mapping>
      

      I have attached the tutorial WAR where you can see the problem by deploying to Tomcat. Simply access the "secure page", login as normal, and it will display. Then logout and click to view the "secure page" again. The login page will display. Login as normal, and on submission you will erroneously see the login page again. The problem can be avoided by disabling the ShallowEtagHeaderFilter in web.xml.

        Issue Links

          Activity

          Hide
          Luke Taylor added a comment -

          It seems that the problem is as follows:

          1. The browser has a cached version of the secure page from a previous login and submits a matching If-None-Match request header with its post-authentication request
          2. The browser gets back the 304 response.
          3. At that point (as far as I understand) it should apparently display the cached page, but instead
          a) Firefox re-requests the previous URL (/spring-security-login)
          b) Safari does nothing (displays a blank page)

          I'm not sure at the moment why that would be the case. In a real application, this shouldn't be an issue as secured pages should not be cached at the client side.

          The problem doesn't occur if you put the ShallowEtagHeaderFilter before the Spring Security filter chain. That way the Etag value changes when the response redirects to the login page.

          Show
          Luke Taylor added a comment - It seems that the problem is as follows: 1. The browser has a cached version of the secure page from a previous login and submits a matching If-None-Match request header with its post-authentication request 2. The browser gets back the 304 response. 3. At that point (as far as I understand) it should apparently display the cached page, but instead a) Firefox re-requests the previous URL (/spring-security-login) b) Safari does nothing (displays a blank page) I'm not sure at the moment why that would be the case. In a real application, this shouldn't be an issue as secured pages should not be cached at the client side. The problem doesn't occur if you put the ShallowEtagHeaderFilter before the Spring Security filter chain. That way the Etag value changes when the response redirects to the login page.
          Hide
          Luke Taylor added a comment - - edited

          I've noticed that Firefox doesn't send the If-None-Match header when it is requesting the original page after a redirect (subsequent to logging in). However the DefaultSavedRequest still returns the original header which was cached prior to forcing a login. This results in the 304 code being sent by the ShallowEtagHeaderFilter, and Firefox doesn't know what to do.

          I've modified DefaultSavedRequest to ignore this header, which fixes the problem. However secure pages should generally have appropriate headers (no-cache etc) set to prevent the browser caching them to begin with.

          Show
          Luke Taylor added a comment - - edited I've noticed that Firefox doesn't send the If-None-Match header when it is requesting the original page after a redirect (subsequent to logging in). However the DefaultSavedRequest still returns the original header which was cached prior to forcing a login. This results in the 304 code being sent by the ShallowEtagHeaderFilter, and Firefox doesn't know what to do. I've modified DefaultSavedRequest to ignore this header, which fixes the problem. However secure pages should generally have appropriate headers (no-cache etc) set to prevent the browser caching them to begin with.

            People

            • Assignee:
              Luke Taylor
              Reporter:
              Ben Alex
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: