Expected CSRF token not found. Has your session expired 403

匿名 (未验证) 提交于 2019-12-03 02:14:01

问题:

I'm trying to write my test spring security application with mkyong examples.

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:

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.

回答1:

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.

Here is my working solution:

  1. Add this hidden input:

    <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />

  2. In your WebSecurityConfig (which extends WebSecurityConfigurerAdapter), 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()) 

I spent lot of time on this problem. Hope it can help someone who has the same problem.



回答2:

If you must disable it...

In Spring Security 4, CSRF is enabled by default when using the XML configuration. Previously it was only enabled by default for the Java-based configuration.

According to Section 14.4.2 of the Spring Security Documentation:

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.

<http>    ...    <csrf disabled="true"/>    ... </http> 


回答3:

Disabling CSRF protection sounds like a bad idea, no?

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.

<%@ 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}"/> 


回答4:

To @St.Antario, Please use this code to enable CSRF in your code

@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;     } } 


回答5:

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

<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

<%@page session="true"%> 

and input hidden:

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!