我正在尝试使用简单的示例编写我的测试弹簧安全应用程序。
Spring Security: 4.0.0.RC1
Spring: 4.1.4.RELEASE
我有以下安全配置:
<http auto-config="true">
<intercept-url pattern="/admin**"
access="hasRole('ADMIN')"/>
<form-login authentication-failure-url="/?auth_error"
username-parameter="user"
password-parameter="password"
login-page="/"
default-target-url="/?OK"/>
<!-- <csrf/> -->
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="mkyong" password="123456" authorities="ADMIN" />
</user-service>
</authentication-provider>
</authentication-manager>
登录页:
<html>
<body>
<form method="POST">
<label for="user">User: </label>
<input type="text" id="user" name="user" /> </br>
<label for="password">Password: </label>
<input type="text" name="password" id="password" /> </br>
<input type="submit" />
</form>
</body>
</html>
现在,当我尝试登录时,我得到403错误页面:
Invalid CSRF Token 'null' was found on the request parameter
'_csrf' or header 'X-CSRF-TOKEN'.
描述:
Access to the specified resource (Invalid CSRF Token 'null' was
found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.) has been
forbidden.
出了什么问题,我该如何解决这个问题?我在配置中评论了csrf
,但错误消息与csrf
有关。
答案 0 :(得分:41)
我遇到了同样的问题。我使用thymeleaf和Spring启动,当我尝试在表单中发布数据时,我遇到了CSRF令牌问题。
这是我的工作解决方案:
添加此隐藏输入:
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
在WebSecurityConfig
(扩展WebSecurityConfigurerAdapter
)中,添加方法:
private CsrfTokenRepository csrfTokenRepository()
{
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setSessionAttributeName("_csrf");
return repository;
}
并在方法configure()
中添加代码:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf()
.csrfTokenRepository(csrfTokenRepository())
我花了很多时间在这个问题上。希望它可以帮助那些有同样问题的人。
答案 1 :(得分:24)
如果你必须禁用它......
在Spring Security 4中,CSRF is enabled by default使用XML配置时。以前,它仅在默认情况下启用基于Java的配置。
根据Section 14.4.2 of the Spring Security Documentation:
从Spring Security 4.0开始,默认情况下使用XML配置启用CSRF保护。如果要禁用CSRF保护,可以在下面看到相应的XML配置。
<http>
...
<csrf disabled="true"/>
...
</http>
答案 2 :(得分:20)
禁用CSRF保护听起来不错,不是吗?
如果您使用Spring的表单标记库,则会自动包含CSRF令牌。它还将HTML Escape表单元素值,这使您的网站对XSS更安全,更正确。
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<form:form>
<form:input...
</form:form>
否则,请将其添加到表单中:
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
答案 3 :(得分:4)
致@ St.Antario, 请使用此代码在代码中启用CSRF
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("*/*").authorizeRequests()
.antMatchers("/", "/login**").permitAll()
.anyRequest().authenticated()
.and().csrf().csrfTokenRepository(csrfTokenRepository())
.and().addFilterAfter(csrfHeaderFilter(), SessionManagementFilter.class);
}
private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null
&& !token.equals(cookie.getValue())) {
// Token is being added to the XSRF-TOKEN cookie.
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
//repository.setSessionAttributeName(("X-XSRF-TOKEN"));
return repository;
}
}
答案 4 :(得分:1)
您的登录页面叫什么名字 它以.jsp结尾
如果登录页面未以.jsp结尾,则Spring框架不会评估JSP或EL表达式