Spring Rest Service - 当我尝试登录时,CSRF 令牌无效

Posted

技术标签:

【中文标题】Spring Rest Service - 当我尝试登录时,CSRF 令牌无效【英文标题】:Spring Rest Service - Invalid CSRF token when I attempt to login 【发布时间】:2015-04-28 04:41:13 【问题描述】:

我有一个 Spring MVC REST 服务,启用了 Spring Security (3.2.5.RELEASE)。当我打开@EnableWebMvcSecurity 时,会在http://localhost:8080/login 自动为我生成一个登录表单。如果我使用此表单登录,一切正常。

当我尝试通过直接发送 POST 请求登录时出现问题。在我的帖子请求中,我提供了用户名和密码。我还包括 http 标头“X-CSRF-TOKEN”,对于标头值,我使用我看到的 JSESSIONID 已在 cookie 中生成。但是当我发送这个 POST 请求时,我得到了以下结果:

HTTP Status 403 - Invalid CSRF Token '29F5E49EFE8D758D4903C0491D56433E' 
was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.

我做错了什么?我是否提供了错误的令牌值?这个 JSESSIONID 是什么?如果我没有为此标头输入值,或者将标头全部省略,它会告诉我“找到空 CSRF 令牌”。

下面是我的 Spring Security 配置:

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception 
        auth.inMemoryAuthentication()
            .withUser("user").password("password").roles("USER");
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
            .authorizeRequests()
                .antMatchers("/secure/**").authenticated()
                .and()
            .formLogin()
                .usernameParameter("username")
                .passwordParameter("password")        
                .and()
            .logout()
                .and()
            .httpBasic()
                .and()
            .csrf(); 
    

非常感谢任何帮助!提前致谢!

【问题讨论】:

在我使用登录表单时仔细检查 HTTP 请求/响应,看来 JSESSIONID 不是 我应该为 X-CSRF-TOKEN 提供的值标题。当我使用表单登录时,我看到请求中包含 CSRF 令牌。如果我需要通过调用 REST 服务来登录用户,我将如何获得此值? 该值可以通过先调用'GET'然后'POST'来获得 【参考方案1】:

(1) 在所有 AJAX 请求中包含 CSRF 令牌。

$(function () 
    var token = $('#logoutform>input').val();
    var header = $('#logoutform>input').attr('name');
    $(document).ajaxSend(function(e, xhr, options) 
        xhr.setRequestHeader('X-CSRF-TOKEN', token);
    );
 );

(2) 简单请求。

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

【讨论】:

【参考方案2】:

您需要在提交登录表单时发送csrf 令牌。请在 html 表单中添加以下行:

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

【讨论】:

【参考方案3】:

你需要&lt;meta name="_csrf" content="$_csrf.token"/&gt;,https://spring.io/blog/2013/08/21/spring-security-3-2-0-rc1-highlights-csrf-protection/#ajax-requests

或者如果您使用的是百里香&lt;meta name="_csrf" th:content="$_csrf.token" /&gt;

【讨论】:

以上是关于Spring Rest Service - 当我尝试登录时,CSRF 令牌无效的主要内容,如果未能解决你的问题,请参考以下文章

关于我的 spring rest service40 的 jQuery 和 403 错误和 cors 问题 [重复]

Spring Boot JPA多对多关系-Rest Web Service无法返回子对象

2.Spring构建REST Web Service

Spring Rest Service 不适用于 XML 响应

spring-boot-mybatis-rest-service-demo

使用 Spring Boot 从另一个服务调用 Rest Service 以进行课程注册系统