gpt4 book ai didi

java - Spring Security 'remember me' cookie 在第一个请求中不可用

转载 作者:搜寻专家 更新时间:2023-10-31 20:34:38 24 4
gpt4 key购买 nike

我在登录请求后未能检索到 Spring 记住我的 cookie,但它在对 protected 页面的下一个请求中工作正常。谁能告诉我怎样才能马上拿到它?

我在登录请求中设置了记住我的 cookie,但在 Spring 重定向回原始( protected )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”和 protected 页面都由 Tomcat 6 中的同一个线程处理。
  5. 我们的 org.springframework.security.web.access.expression.WebSecurityExpressionRoot 子类具有从 调用的方法
  6. 在我们的 method() 中,request.getCookies() 不会在第一次请求时提供记住我的 cookie,而是在之后的所有请求中提供。
  7. 我们的应用程序有一些问题,因为缺少 cookie...

到目前为止,我的理论是我没有正确理解 SavedRequest。

这里是压缩配置:

<http auto-config="false" use-expressions="true" authentication-manager-ref="myAuthenticationManager" path-type="regex">
<form-login authentication-success-handler-ref="myAuthenticationSuccessHandler" login-page="..." login-processing-url="..." authentication-failure-url="..." username-parameter="username" password-parameter="password" />

<custom-filter ref="logoutFilter" position="LOGOUT_FILTER"/>
<expression-handler ref="myWebSecurityExpressionHandler" />

<custom-filter ref="myCustomeFilter1" before="FORM_LOGIN_FILTER"/>
<custom-filter ref="myCustomeFilter2" position="BASIC_AUTH_FILTER"/>
<custom-filter ref="mySecurityClientTokenAuthenticationFilter" after="LOGOUT_FILTER" />

<access-denied-handler ref="myAccessDeniedHandler"/>
<intercept-url pattern="xxx"
access="method()"/>

<intercept-url pattern="yyy"
access="method()"/>
<remember-me services-ref="rememberMeServices" key="my_remember"/>
</http>

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

<http ...
<request-cache ref="nullRequestCache"/>
</http>
<bean:bean id="nullRequestCache" class="org.springframework.security.web.savedrequest.NullRequestCache"/>

最佳答案

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

@Override
public Cookie[] getCookies() {
List<Cookie> 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 年 3 月 5 日更新

因为spring security会对原始的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...

}

}

关于java - Spring Security 'remember me' cookie 在第一个请求中不可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20421641/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com