我为springframework RESTful服务配置了Springframework安全性(4.0)。对于浏览器启动的GET访问,以及html形式,其中action = GET,但是对于where = requestMethod.POST的服务失败,或者通过提交带有action = POST的HTML表单来自浏览器;或者从远程应用程序使用RestTemplate。
要查看问题,我将配置简化为以下内容。有了这个,我可以访问Method = GET的所有服务,而不会受到凭证的挑战(似乎是正确的),但是接收到了“accessDeniedPage”的失败(我从来没有受到过凭证的挑战)
所有服务都在“/ CouponController / **”下:
@Override
protected void configure (HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/CouponController/**").permitAll()
.and().formLogin().permitAll()
.and().exceptionHandling().accessDeniedPage("/Accesses_Denied_Due_To_Security_failure");
}
如果我使用以下配置,在访问method = GET的服务时我将面临凭证的挑战,而在访问Method = POST的服务时仍会看到相同的行为:
@Override
protected void configure (HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/CouponController/**").access("hasRole('STAFF')")
.and().formLogin().permitAll()
.and().exceptionHandling().accessDeniedPage("/Accesses_Denied_Due_To_Security_failure");
}
我做错了什么?
答案 0 :(得分:1)
失败的原因是因为表单中没有CSRF令牌。
如果您在页面上添加以下Spring表单taglib:
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
在JSP中使用Springs <form:form>
标记而不是标准HTML <form>
,它会自动将(强烈推荐的)CSRF令牌添加到表单中。
这样会更安全,也是一种很好的做法,而不是禁用该功能。
或者,如果您想使用标准HTML <form>
,可以添加以下隐藏字段,Spring Security将处理其余内容:
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
答案 1 :(得分:0)
我找到了表单提交失败的原因。
默认情况下,spring security启用csrf,用于XML和Java配置。这导致我的代码无法提交表单,因为我提交的表单不包含csrf令牌。不幸的是,当我使用Java配置时,错误消息只是“404请求的资源不可用”。当我切换到XML配置时,错误消息变得有用。
禁用csrf后,表单提交成功。现在,我需要回过头来,弄清楚如何在我的表单中包含一个csrf标记。
希望这有帮助。