使用 CSRF 登录后如何启用 Spring Security POST 重定向?
Posted
技术标签:
【中文标题】使用 CSRF 登录后如何启用 Spring Security POST 重定向?【英文标题】:How to enable Spring Security POST redirect after log in with CSRF? 【发布时间】:2014-03-24 08:55:50 【问题描述】:我正在使用带有 CSRF 的 Spring Security 3.2。我的配置包括:
<csrf />
<form-login default-target-url="/defaultPage"/>
当用户进行需要身份验证的 POST 表单提交(使用 CSRF 令牌)时,他将被重定向到登录页面。之后,Spring Security 将用户重定向到defaultPage
,而不是提交请求。
我怀疑问题是 CSRF 令牌在登录期间被重置。
登录工作后如何获得这样的POST重定向?
更新:我尝试创建自定义 SavedRequestAwareAuthenticationSuccessHandler
以重定向到原始 POST 请求。但是,我看到原始请求甚至没有保存在 requestCache
中。
【问题讨论】:
我很想听听这个问题的答案。解释如何使用 Spring Security 实现它,或者可能解释它本质上是不安全的,因此不应该/不能使用 Spring Security 来完成。 【参考方案1】:似乎启用CSRF保护时,如果请求使用GET
方法,Spring Security只会将您的原始请求放在requestCache
中。为了让它也缓存POST
请求,我创建了一个自定义requestCache
。
我不是 100% 相信这样做不会以某种方式削弱 CSRF 保护,但在我看来这似乎是安全的。
将请求缓存 bean 添加到 XML 配置中:
<bean id="requestCache" class="a.b.c.AlwaysSaveRequestCache" />
<http>
<csrf />
<request-cache ref="requestCache" />
</http>
通过扩展和借用HttpSessionRequestCache
的代码来实现自定义请求缓存:
public class AlwaysSaveRequestCache extends HttpSessionRequestCache
@Override
public void saveRequest(HttpServletRequest request, HttpServletResponse response)
final String SAVED_REQUEST = "SPRING_SECURITY_SAVED_REQUEST";
DefaultSavedRequest savedRequest = new DefaultSavedRequest(request, new PortResolverImpl());
request.getSession().setAttribute(SAVED_REQUEST, savedRequest);
logger.debug("DefaultSavedRequest added to Session: " + savedRequest);
您的POST
请求现在应该被缓存并在被登录表单中断后重新发送。
【讨论】:
请注意,您可能并不总是希望将 POST 保存到请求缓存中,因为它可能会导致此处描述的问题:***.com/questions/4854480/…。我正在研究使用这种“AlwaysSaveRequestCache”的变体,它只允许保存 POST 请求 URL 的白名单(除了默认的请求匹配器行为)。【参考方案2】:这很简单。不要以隐藏的形式传递 CSRF 令牌,它不会起作用将 CSRF token
直接作为 query params
传递给 URL
,如下所示
<c:url value="/jobseeker/resume/uploadJobSeekerResume1?$_csrf.parameterName=$_csrf.token" var="uploadResumeURL"/>
<form:form action="$uploadResumeURL" method="post" enctype="multipart/form-data">
<input id="file" name="file" type="file" />
<div class="modal-footer">
<button type="submit" class="btn btn-success" >
<span class="glyphicon glyphicon-ok-sign"></span> Save
</button>
</div>
</form:form>
【讨论】:
【参考方案3】:这是因为 HttpSessionRequestCache 和 DefaultSavedRequest 不是为使用“multipart/form-data”而设计的。多部分请求被视为常规请求,所有表单数据都将丢失。从 SavedRequest 恢复的请求将只包含 URL 和方法。
【讨论】:
【参考方案4】:我可能有些不明白...但是你不能从你的配置中删除 default-target-url 吗?
【讨论】:
如果不指定目标url,Spring Security会重定向到域“/”的根目录,而不是提交之前的请求。启用/使用 CSRF 保护时会发生此问题。 GET 请求不会发生这种情况(没有 CSRF 令牌)。以上是关于使用 CSRF 登录后如何启用 Spring Security POST 重定向?的主要内容,如果未能解决你的问题,请参考以下文章
在 Spring Security 中启用 CSRF 时,访问被拒绝 403
Springs CSRF 保护 HTML *only* 登录页面
如何在 JSF-Spring 集成应用中启用 CSRF 保护