在第一次请求中,Spring安全’记住我’的cookie不可用

我无法在登录请求后检索Spring记住我的cookie,但它在下一个对受保护页面的请求中工作正常。 谁能告诉我如何立即掌握它?

我在登录请求中设置了记住我的cookie,但是在Spring重定向回原始(受保护的)URL之后无法对其进行检索。

一步步:

  1. 浏览器转到example.com/protected
  2. Spring重定向到登录表单页面
  3. 成功登录后,SPRING_SECURITY_REMEMBER_ME_COOKIE设置在一个非常薄的自定义子类org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices中
  4. 看起来Spring重定向回example.com/protected,没有往返浏览器,并且登录“servlet”和受保护页面都由Tomcat 6中的同一个线程处理。
  5. 我们的org.springframework.security.web.access.expression.WebSecurityExpressionRoot的子类具有从调用的方法
  6. 在我们的method()中,request.getCookies()不会在第一个请求中给出记住我的cookie,而是在之后的所有请求中。
  7. 我们的应用程序存在一些问题,因为缺少cookie …

到目前为止,我的理论是我不理解SavedRequest。

压缩配置在这里:

            

我尝试添加以下内容,唯一的结果是用户没有被重定向到原始页面。

 <http ...    

在RememberMeService的autoLogin()方法中使用request.getCookie()时,传入的请求是SavedRequestAwareWrapper,它封装原始请求和保存的请求并覆盖getCookies方法。

 @Override public Cookie[] getCookies() { List cookies = savedRequest.getCookies(); return cookies.toArray(new Cookie[cookies.size()]); } 

因此,当您想要从请求获取cookie时,您实际上从savedRequest获取cookie。 但是,cookie可能存在于原始请求中。

你可能应该得到你想要的cookie的原始请求。 例如:

 public class ApplicationRememberMeServiceImpl implements RememberMeService, LogoutHandler { public Authentication autoLogin(HttpServletRequest request, HttpServletResponse response) { HttpServletRequestWrapper savedRequestWrapper = (HttpServletRequestWrapper) ((HttpServletRequestWrapper) request).getRequest(); HttpServletRequest httpServletRequest = (HttpServletRequest) savedRequestWrapper.getRequest(); Cookie cookie = WebUtils.getCookie(httpServletRequest, cookieName); // logic continues... } } 

2015年5月5日更新

因为spring安全性会多次包装原始的HttpServletRequest,所以以下面的方式提取原始请求更安全:

 public class ApplicationRememberMeServiceImpl implements RememberMeService, LogoutHandler { public Authentication autoLogin(HttpServletRequest request, HttpServletResponse response) { HttpServletRequest httpServletRequest = request; // Get the original request from multiple wrapped HttpServletRequest if(httpServletRequest instanceof HttpServletRequestWrapper) { HttpServletRequestWrapper httpServletRequestWrapper = (HttpServletRequestWrapper) httpServletRequest; while(httpServletRequestWrapper.getRequest() instanceof HttpServletRequestWrapper) { httpServletRequestWrapper = (HttpServletRequestWrapper) httpServletRequestWrapper.getRequest(); } httpServletRequest = (HttpServletRequest) httpServletRequestWrapper.getRequest(); } Cookie cookie = WebUtils.getCookie(httpServletRequest, cookieName); // logic continues... } }