【发布时间】:2014-07-03 09:07:50
【问题描述】:
我在我的 Spring MVC 应用程序中使用 Spring Security 3.2.3 并得到一些意外行为。
根据documentation here,应该可以在我的html的meta标签中使用${_csrf.token}:
<meta name="_csrf" content="${_csrf.token}" />
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf.headerName}" />
我使用 JQuery 提取“内容”的值并使用 AJAX 将其放入请求标头中。
尽管出于某种原因,Spring Security 并未将其“转换”为实际令牌,它只是作为文字字符串“${_csrf.token}”发送到标头中。
根据文档尝试在隐藏输入中使用${_csrf.token} 的替代路线,然后我尝试通过检查输入的值来检查令牌的评估结果,但它仍然只是纯文本“${_csrf.token} ”。
既然 Spring Security 似乎没有生效,我是否缺少某种配置?我目前正在使用准系统 Spring Security Java 配置(而不是 xml),如下所示:
import org.springframework.context.annotation.*;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.*;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf();
}
}
我知道 configure 会被调用,因为我在其中放了一个调试语句,所以我假设 CSRF 保护确实已启用,因为它应该是默认的。
我意识到语法“${}”是 JSP 表达式语言,我目前正在成功地使用它来将上下文评估为带有 Thymeleaf 的对象,例如:
th:object="${context}"
所以我尝试在元标记的“内容”前面添加“th:”,如下所示:
<meta name="_csrf" th:content="${_csrf.token}"/>
但是会导致 this 无法评估的异常:
评估 SpringEL 表达式的异常:“_csrf.token”
我认为这里的关键可能是弄清楚如何让表达式在我看来正确评估。
【问题讨论】:
-
“${_csrf.token}”语法是否可能仅适用于 JSP,而不适用于 .html 文件?
-
现在的问题是,在运行 Spring Security 时,即使我们已经设置了身份验证方法,它也很烦人地想要对用户进行身份验证,所以我收到了一个未经授权的错误。我需要找出如何绕过 Spring Security 的默认身份验证要求......似乎没有简单的方法可以将其关闭,如果您不包含身份验证配置,整个应用程序将拒绝运行(令人抓狂!)。我只想要这个框架的 CSRF 功能!将继续调查如何绕过...
-
所以经过反复测试,似乎 Spring Security 确实运行了,但我仍然只得到 ${_csrf.token} 的字符串。我认为这与我在需要 JSP 来评估值时使用 .html 文件有关,但是将其更改为 .jsp 文件会导致“org.thymeleaf.exceptions.TemplateInputException:解析模板时出错 {myapplication},模板可能不存在或可能无法被任何已配置的模板解析器访问”
-
只是说两个 META 元素中的
th:content="${_csrf.whateverProperty}"表单确实对我有用。弹簧 4.1.x、弹簧安全 4.0.x、Thymeleaf 2.1.x。如果我使用无效的属性名称,我会得到 SpelEvaluationException。在报告原始问题时,您遇到了其他一些配置问题。
标签: spring-mvc spring-security csrf thymeleaf