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'.- 1
- 1
然后我上網查找了這個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
@Overrideprotected 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();}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
參考資料:?
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
總結
以上是生活随笔為你收集整理的spring security CSRF 问题 Invalid CSRF Token 'null' was found on ......的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: springboot 定制个性 bann
- 下一篇: springboot-springSec