spring security CSRF 问题 Invalid CSRF Token ‘null’ was found on

1. 问题

前面几篇博客 spring security在集成spring boot的微服务框架后,实现了cas认证和权限控制。但是在使用 postman 进行调用的时候出现这个问题

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

然后我上网查找了这个CSRF 资料整理如下:

Spring Security 4.0之后,引入了CSRF,默认是开启。不得不说,CSRF和RESTful技术有冲突。CSRF默认支持的方法: GET|HEAD|TRACE|OPTIONS,不支持POST。

科普一下,什么是csrf,这是一个web应用安全的问题,CSRF(Cross-site request forgery跨站请求伪造,也被称为“One Click Attack” 或者Session Riding,攻击方通过伪造用户请求访问受信任站点。

我们知道,客户端与服务端在基于http协议在交互的数据的时候,由于http协议本身是无状态协议,后来引进了cookie的 方式进行记录服务端和客户端的之间交互的状态和标记。cookie里面一般会放置服务端生成的session id(会话ID)用来识别客户端访问服务端过 程中的客户端的身份标记。

在跨域 (科普一下:同一个ip、同一个网络协议、同一个端口,三者都满足就是同一个域,否则就有跨域问题) 的情况下, session id可能会被恶意第三方劫持,此时劫持这个session id的第三方会根据这个session id向服务器发起请求,此时服务器收到这个请求会 认为这是合法的请求,并返回根据请求完成相应的服务端更新。

比较关键的一点是,

如果这个http请求是get方式发起的请求,意味着它只是访问服务器 的资源,仅仅只是查询,没有更新服务器的资源,所以对于这类请求,spring security的防御策略是允许的,

如果这个请求是通过post请求发起的, 那么spring security是默认拦截这类请求的,因为这类请求是带有更新服务器资源的危险操作,如果恶意第三方可以通过劫持session id来更新 服务器资源,那会造成服务器数据被非法的篡改,所以这类请求是会被Spring security拦截的,在默认的情况下,spring security是启用csrf 拦截功能的,这会造成,在跨域的情况下,post方式提交的请求都会被拦截无法被处理(包括合理的post请求),前端发起的post请求后端无法正常 处理,虽然保证了跨域的安全性,但影响了正常的使用,如果关闭csrf防护功能,虽然可以正常处理post请求,但是无法防范通过劫持session id的非法的post请求,所以spring security为了正确的区别合法的post请求,采用了token的机制。

在跨域的场景下,客户端访问服务端会首先发起get请求,这个get请求在到达服务端的时候,服务端的Spring security会有一个过滤 器 CsrfFilter去检查这个请求,如果这个request请求的http header里面的X-CSRF-COOKIE的token值为空的时候,服务端就好自动生成一个 token值放进这个X-CSRF-COOKIE值里面,客户端在get请求的header里面获取到这个值,如果客户端有表单提交的post请求,则要求客户端要 携带这个token值给服务端,在post请求的header里面设置_csrf属性的token值,提交的方式可以是ajax也可以是放在form里面设置hidden 属性的标签里面提交给服务端,服务端就会根据post请求里面携带的token值进行校验,如果跟服务端发送给合法客户端的token值是一样的,那么 这个post请求就可以受理和处理,如果不一样或者为空,就会被拦截。由于恶意第三方可以劫持session id,而很难获取token值,所以起到了 安全的防护作用。

 

2. 解决

原因找到了:spring Security 3默认关闭csrf,Spring Security 4默认启动了csrf。
解决方案:
如果不采用csrf,可禁用security的csrf

Java注解方式配置:

加上 .csrf().disable()即可。

修改前WebSecurityConfig.java

@Override
   protected void configure(HttpSecurity http) throws Exception {
       http.authorizeRequests()
               .antMatchers("/", "/home").permitAll()
               .and()
               .formLogin()
               .loginPage("/login").permitAll()
               .and()
               .logout().logoutUrl("/logout")
               .logoutSuccessUrl("/hello")
               .permitAll();
       http.addFilterBefore(customizeFilterSecurityInterceptor, FilterSecurityInterceptor.class)
               .csrf().disable();
   }

参考资料:
http://blog.csdn.net/icanactnow2/article/details/53515844
http://group.jobbole.com/24128/
http://www.cnblogs.com/yjmyzz/p/customize-CsrfFilter-to-ignore-certain-post-http-request.html

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CSRF token invalid是一个常见的错误信息,通常出现在服务端无法接受post请求时。CSRF(跨站请求伪造)是一种web攻击方式,目的是利用用户在一个网站上已登录的身份来进行恶意操作。为了防止这种攻击,服务端会生成一个CSRF token,并将其与表单一起发送给客户端。客户端在发送post请求时需要将该token作为请求的一部分发送给服务端。服务端会比对请求中的CSRF token和自己生成的token是否一致,如果不一致,则会返回"invalid csrf token"错误信息。 要解决CSRF token invalid错误,有几种可能的解决方案。一种是在服务端的配置文件中关闭CSRF防范,这样可以避免在本地测试时出现该错误。另一种解决方案是增加适当的插件,比如yhsd-api插件,在使用该插件后,可以直接通过app.Yhsd获取yhsd-api,无需额外的require('yhsd-api')操作。同时,该插件还提供了一些常用的方法,可以帮助处理CSRF token相关的问题。 总结起来,解决CSRF token invalid错误的方法主要包括关闭CSRF防范和使用适当的插件来处理CSRF token。具体的实现方式可以根据你的需求和具体的技术栈来选择。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Egg post 失败 { message: 'invalid csrf token' } 解决方案](https://blog.csdn.net/weixin_43704471/article/details/90763103)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [yhsd-egg:友好速搭插件开发egg.js:egg:扩展框架——yhsd-egg:egg:!](https://download.csdn.net/download/weixin_42123456/18521303)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值