Note that there are some explanatory texts on larger screens.

plurals
  1. POSpring Security 3.1.0 - Remember-me does not work as expected
    primarykey
    data
    text
    <p>I am having a problem with Spring Security's 3.1.0 remember-me cookies. I need to find a solution ASAP and I cannot find the cause of this problem.</p> <p>These are the steps I am following:</p> <ul> <li>Go to my app URL (e.g. <a href="http://myapp/app.htm" rel="nofollow">http://myapp/app.htm</a>)</li> <li>I am redirected to login page, so I log in</li> <li>Once logged in, close browser without logging out</li> <li>Open browser and go to my app URL</li> </ul> <p>At this point I expect to enter my app bypassing the login form since the remember-me cookie is still in my browser. Despite that fact, <strong>the login page appears again</strong>.</p> <ul> <li>Go to my app URL again</li> </ul> <p>Trying again, I can enter my app normally bypassing the login form.</p> <p>This is quite confusing, and I cannot find an explanation so far.</p> <p>I tried to debug both attempts and I found the following when Spring Security's RememberMeAuthenticationFilter was fired:</p> <p>Attempt 1<br/> request path = /app.htm: request.getCookies() did not contain my SPRING_SECURITY_REMEMBER_ME_COOKIE, therefore I was redirected to login page request path = /security/login.htm: at this point request.getCookies() DID have my SPRING_SECURITY_REMEMBER_ME_COOKIE, and it was accepted; anyway, I had already been redirected to the login page</p> <p>Attempt 2<br/> The remember-me cookie had already been accepted, so I could enter my app without problem.</p> <p>Below are the Spring Security XML configuration and the logs of both attempts.</p> <p>Any help on this will be very much appreciated!</p> <hr> <p>Spring Security configuration (I will omit everything about daoAuthenticationProvider and event listeners):</p> <pre><code>&lt;sec:http auto-config="false" use-expressions="true" authentication-manager-ref="authenticationManager"&gt; &lt;sec:custom-filter ref="sessionLocaleResolvingFilter" before="FORM_LOGIN_FILTER"/&gt; &lt;sec:intercept-url pattern="/security/*.htm" requires-channel="https" /&gt; &lt;sec:intercept-url pattern="/retrieve-password/*.htm" requires-channel="https" /&gt; &lt;sec:intercept-url pattern="/messagebroker/*" access="authenticated" requires-channel="http" /&gt; &lt;sec:intercept-url pattern="/platform/*.htm" access="hasRole('limited') or (authenticated and !hasRole('role1') and !hasRole('role2'))" requires-channel="http" /&gt; &lt;sec:intercept-url pattern="/app.htm" access="authenticated" requires-channel="http" /&gt; &lt;sec:intercept-url pattern="/**" requires-channel="http" /&gt; &lt;sec:form-login login-page="/security/login.htm" default-target-url="/app.htm" login-processing-url="/security/process-login.htm" authentication-failure-url="/security/login.htm?error=true" /&gt; &lt;sec:logout logout-url="/security/logout.htm" delete-cookies="JSESSIONID,SPRING_SECURITY_REMEMBER_ME_COOKIE" logout-success-url="/security/logout-success.htm" invalidate-session="true"/&gt; &lt;sec:anonymous/&gt; &lt;sec:remember-me use-secure-cookie="true" key="myAppServices" services-ref="ipTokenBasedRememberMeServicesBean" /&gt; &lt;sec:session-management session-fixation-protection="none"/&gt; &lt;sec:access-denied-handler error-page="/denied-access.htm"/&gt; &lt;/sec:http&gt; &lt;bean id="sessionLocaleResolvingFilter" class="com.myapp.spring.security.SessionLocaleResolvingFilter" /&gt; &lt;bean class="com.myapp.spring.security.IPTokenBasedRememberMeServices" id="ipTokenBasedRememberMeServicesBean"&gt; &lt;constructor-arg value="myAppServices"/&gt; &lt;constructor-arg ref="myAppJdbcDaoImpl"/&gt; &lt;/bean&gt; &lt;bean id="myAppPasswordEncoder" class="com.myapp.spring.security.MyAppPasswordEncoder" /&gt; &lt;bean id="authenticationManager" class="o.s.s.authentication.ProviderManager"&gt; &lt;property name="providers"&gt; &lt;list&gt; &lt;ref local="daoAuthenticationProvider" /&gt; &lt;/list&gt; &lt;/property&gt; &lt;/bean&gt; &lt;!-- Other beans... --&gt; </code></pre> <p>Log for the first attempt (replaced org.springframework with o.s and org.springframework.security with o.s.s):</p> <pre><code>o.s.s.web.access.channel.ChannelProcessingFilter:134 - Request: FilterInvocation: URL: /app.htm?lang=en; ConfigAttributes: [REQUIRES_INSECURE_CHANNEL] o.s.s.web.context.HttpSessionSecurityContextRepository:127 - No HttpSession currently exists o.s.s.web.context.HttpSessionSecurityContextRepository:85 - No SecurityContext was available from the HttpSession: null. A new one will be created. o.s.s.web.FilterChainProxy:318 - /app.htm?lang=en at position 9 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter' o.s.s.web.authentication.AnonymousAuthenticationFilter:102 - Populated SecurityContextHolder with anonymous token: 'o.s.s.authentication.AnonymousAuthenticationToken@90550640: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: o.s.s.web.authentication.WebAuthenticationDetails@7798: RemoteIpAddress: fe80:0:0:0:ec09:25fb:3df4:323b; SessionId: 057E689401E69589BB7359F3E95B4A18; Granted Authorities: ROLE_ANONYMOUS' o.s.s.web.FilterChainProxy:318 - /app.htm?lang=en at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter' o.s.s.web.FilterChainProxy:318 - /app.htm?lang=en at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor' o.s.s.web.util.AntPathRequestMatcher:103 - Checking match of request : '/app.htm'; against '/messagebroker/*' o.s.s.web.util.AntPathRequestMatcher:103 - Checking match of request : '/app.htm'; against '/app.htm' o.s.s.web.access.intercept.FilterSecurityInterceptor:193 - Secure object: FilterInvocation: URL: /app.htm?lang=en; Attributes: [authenticated] o.s.s.web.access.intercept.FilterSecurityInterceptor:298 - Previously Authenticated: o.s.s.authentication.AnonymousAuthenticationToken@90550640: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: o.s.s.web.authentication.WebAuthenticationDetails@7798: RemoteIpAddress: fe80:0:0:0:ec09:25fb:3df4:323b; SessionId: 057E689401E69589BB7359F3E95B4A18; Granted Authorities: ROLE_ANONYMOUS o.s.s.access.vote.AffirmativeBased:65 - Voter: o.s.s.web.access.expression.WebExpressionVoter@1ce3388, returned: -1 o.s.s.web.access.ExceptionTranslationFilter:165 - Access is denied (user is anonymous); redirecting to authentication entry point o.s.s.access.AccessDeniedException: Access is denied at o.s.s.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83) at o.s.s.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:205) at o.s.s.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:114) at o.s.s.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) at o.s.s.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) at o.s.s.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) at o.s.s.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) (X more) o.s.s.web.DefaultRedirectStrategy:36 - Redirecting to 'http://arbad67464/services/security/login.htm' o.s.s.web.context.HttpSessionSecurityContextRepository:269 - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession. o.s.s.web.context.SecurityContextPersistenceFilter:97 - SecurityContextHolder now cleared, as request processing completed o.s.s.web.access.channel.RetryWithHttpsEntryPoint:55 - Redirecting to: https://arbad67464/services/security/login.htm o.s.s.web.DefaultRedirectStrategy:36 - Redirecting to 'https://arbad67464/services/security/login.htm' o.s.s.web.access.channel.ChannelProcessingFilter:134 - Request: FilterInvocation: URL: /security/login.htm; ConfigAttributes: [REQUIRES_SECURE_CHANNEL] o.s.s.web.FilterChainProxy:318 - /security/login.htm at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter' o.s.s.web.context.HttpSessionSecurityContextRepository:139 - HttpSession returned null object for SPRING_SECURITY_CONTEXT o.s.s.web.context.HttpSessionSecurityContextRepository:85 - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@16de87. A new one will be created. o.s.s.web.FilterChainProxy:318 - /security/login.htm at position 3 of 11 in additional filter chain; firing Filter: 'LogoutFilter' o.s.s.web.FilterChainProxy:318 - /security/login.htm at position 4 of 11 in additional filter chain; firing Filter: 'SessionLocaleResolvingFilter' o.s.s.web.FilterChainProxy:318 - /security/login.htm at position 5 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter' o.s.s.web.FilterChainProxy:318 - /security/login.htm at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter' o.s.s.web.FilterChainProxy:318 - /security/login.htm at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter' o.s.s.web.FilterChainProxy:318 - /security/login.htm at position 8 of 11 in additional filter chain; firing Filter: 'RememberMeAuthenticationFilter' com.myapp.spring.security.IPTokenBasedRememberMeServices:103 - Remember-me cookie detected com.myapp.spring.security.IPTokenBasedRememberMeServices:118 - Remember-me cookie accepted o.s.s.authentication.ProviderManager:152 - Authentication attempt using o.s.s.authentication.RememberMeAuthenticationProvider </code></pre> <p>Log of my second attempt:</p> <pre><code>o.s.s.web.access.channel.ChannelProcessingFilter:134 - Request: FilterInvocation: URL: /app.htm?lang=en; ConfigAttributes: [REQUIRES_INSECURE_CHANNEL] o.s.s.web.context.HttpSessionSecurityContextRepository:158 - Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'o.s.s.core.context.SecurityContextImpl@7db9504: Authentication: o.s.s.authentication.RememberMeAuthenticationToken@7db9504: Principal: com.myapp.spring.security.MyAppUserImpl@9716c62c: Username: somebody@mail.com; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: limited,premium,special; Credentials: [PROTECTED]; Authenticated: true; Details: o.s.s.web.authentication.WebAuthenticationDetails@7798: RemoteIpAddress: fe80:0:0:0:ec09:25fb:3df4:323b; SessionId: 057E689401E69589BB7359F3E95B4A18; Granted Authorities: limited, premium, special' o.s.s.web.FilterChainProxy:318 - /app.htm?lang=en at position 8 of 11 in additional filter chain; firing Filter: 'RememberMeAuthenticationFilter' o.s.s.web.authentication.rememberme.RememberMeAuthenticationFilter:142 - SecurityContextHolder not populated with remember-me token, as it already contained: 'o.s.s.authentication.RememberMeAuthenticationToken@7db9504: Principal: com.myapp.spring.security.MyAppUserImpl@9716c62c: Username: somebody@mail.com; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: limited,premium,special; Credentials: [PROTECTED]; Authenticated: true; Details: o.s.s.web.authentication.WebAuthenticationDetails@7798: RemoteIpAddress: fe80:0:0:0:ec09:25fb:3df4:323b; SessionId: 057E689401E69589BB7359F3E95B4A18; Granted Authorities: limited, premium, special' o.s.s.web.FilterChainProxy:318 - /app.htm?lang=en at position 9 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter' o.s.s.web.authentication.AnonymousAuthenticationFilter:107 - SecurityContextHolder not populated with anonymous token, as it already contained: 'o.s.s.authentication.RememberMeAuthenticationToken@7db9504: Principal: com.myapp.spring.security.MyAppUserImpl@9716c62c: Username: somebody@mail.com; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: limited,premium,special; Credentials: [PROTECTED]; Authenticated: true; Details: o.s.s.web.authentication.WebAuthenticationDetails@7798: RemoteIpAddress: fe80:0:0:0:ec09:25fb:3df4:323b; SessionId: 057E689401E69589BB7359F3E95B4A18; Granted Authorities: limited, premium, special' o.s.s.web.access.intercept.FilterSecurityInterceptor:193 - Secure object: FilterInvocation: URL: /app.htm?lang=en; Attributes: [authenticated] o.s.s.web.access.intercept.FilterSecurityInterceptor:298 - Previously Authenticated: o.s.s.authentication.RememberMeAuthenticationToken@7db9504: Principal: com.myapp.spring.security.MyAppUserImpl@9716c62c: Username: somebody@mail.com; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: limited,premium,special; Credentials: [PROTECTED]; Authenticated: true; Details: o.s.s.web.authentication.WebAuthenticationDetails@7798: RemoteIpAddress: fe80:0:0:0:ec09:25fb:3df4:323b; SessionId: 057E689401E69589BB7359F3E95B4A18; Granted Authorities: limited, premium, special o.s.s.access.vote.AffirmativeBased:65 - Voter: o.s.s.web.access.expression.WebExpressionVoter@1ce3388, returned: 1 o.s.s.web.access.intercept.FilterSecurityInterceptor:214 - Authorization successful </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload