Java 未找到预期的 CSRF 令牌。您的会话是否已过期 403
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28138864/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Expected CSRF token not found. Has your session expired 403
提问by St.Antario
I'm trying to write my test spring security application with mkyong examples.
我正在尝试使用 mkyong 示例编写我的测试 spring 安全应用程序。
Spring Security: 4.0.0.RC1
Spring: 4.1.4.RELEASE
I have the following security config:
我有以下安全配置:
<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>
login-page:
登录页面:
<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>
Now, when I try to login I get 403 error page:
现在,当我尝试登录时,出现 403 错误页面:
Invalid CSRF Token 'null' was found on the request parameter
'_csrf' or header 'X-CSRF-TOKEN'.
description:
描述:
Access to the specified resource (Invalid CSRF Token 'null' was
found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.) has been
forbidden.
What's wrong, how can I fix that? I commented csrf
in the config, but the error-message has to do with the csrf
.
怎么了,我该如何解决?我csrf
在配置中进行了评论,但错误消息与csrf
.
回答by Todd
If you must disable it...
如果您必须禁用它...
In Spring Security 4, CSRF is enabled by defaultwhen using the XML configuration. Previously it was only enabled by default for the Java-based configuration.
在 Spring Security 4 中,使用 XML 配置时默认启用 CSRF。以前,它仅在默认情况下为基于 Java 的配置启用。
According to Section 14.4.2 of the Spring Security Documentation:
根据Spring Security 文档的第 14.4.2 节:
As of Spring Security 4.0, CSRF protection is enabled by default with XML configuration. If you would like to disable CSRF protection, the corresponding XML configuration can be seen below.
从 Spring Security 4.0 开始,默认情况下使用 XML 配置启用 CSRF 保护。如果您想禁用 CSRF 保护,可以在下面看到相应的 XML 配置。
<http>
...
<csrf disabled="true"/>
...
</http>
回答by Neil McGuigan
Disabling CSRF protection sounds like a bad idea, no?
禁用 CSRF 保护听起来是个坏主意,不是吗?
If you use Spring's Form Tag library the CSRF token will be automatically included. It will also HTML Escape form element values, which makes your site safer against XSS, and more correct.
如果您使用 Spring 的 Form Tag 库,CSRF 令牌将自动包含在内。它还将 HTML 转义表单元素值,这使您的站点更安全地抵御 XSS,并且更正确。
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<form:form>
<form:input...
</form:form>
Otherwise, add this to your form:
否则,将其添加到您的表单中:
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
回答by Yinghua
I had the same problem. I use thymeleaf and Spring boot, and got the CSRF token issue when I try to post data in a form.
我有同样的问题。我使用 thymeleaf 和 Spring boot,当我尝试在表单中发布数据时遇到了 CSRF 令牌问题。
Here is my working solution:
这是我的工作解决方案:
Add this hidden input:
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
In your
WebSecurityConfig
(which extendsWebSecurityConfigurerAdapter
), add a method:private CsrfTokenRepository csrfTokenRepository() { HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository(); repository.setSessionAttributeName("_csrf"); return repository; }
and add code in method
configure()
:@Override protected void configure(HttpSecurity http) throws Exception { http.csrf() .csrfTokenRepository(csrfTokenRepository())
添加此隐藏输入:
<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())
I spent lot of time on this problem. Hope it can help someone who has the same problem.
我在这个问题上花了很多时间。希望它可以帮助有同样问题的人。
回答by Java_Fire_Within
To @St.Antario, Please use this code to enable CSRF in your code
致@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;
}
}
回答by Carlos Alberto Gonzalez
spring-security.xml
spring-security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<http pattern="/resources/**" security="none" />
<http use-expressions="true">
<intercept-url pattern="/login*" access="isAnonymous()" />
<intercept-url pattern="/**" access="isAuthenticated()"/>
<form-login
login-page="/login"
default-target-url="/home"
authentication-failure-url="/login?error=true" />
<logout
logout-success-url="/login"
delete-cookies="JSESSIONID" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="carlos" password="123" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
web.xml
网页.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml, /WEB-INF/spring-security.xml</param-value>
</context-param>
add add jsp login
添加添加jsp登录
<%@page session="true"%>
and input hidden:
并输入隐藏:
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
回答by johnmin
What is your login page named Is it ending with .jsp
您的登录页面名称是什么 以 .jsp 结尾
If the login page is not ending with .jsp Spring framework doesn't evaluate the JSP or EL expressions
如果登录页面不以 .jsp 结尾 Spring 框架不会评估 JSP 或 EL 表达式