Spring Boot使用Spring Security POST無法訪問解決方案

在《Spring Boot基於SpringSecurity設置swagger2訪問權限》一文中我們集成了SpringSecurity,但是在使用的過程中發現一個問題,就是get請求可以正常訪問,而post的請求卻無法訪問。

再三檢查了對url路徑權限的匹配,都沒有問題。上篇文章中對應的SecurityConfig配置如下:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests()
				.antMatchers("/api/**").permitAll() 
				.anyRequest().authenticated()
				.and()
				.formLogin()
				.permitAll();
	}
}

api的post請求返回結果信息如下:

{
  "timestamp": "2020-03-24T12:44:12.782+0000",
  "status": 403,
  "error": "Forbidden",
  "message": "Forbidden",
  "path": "/api/check"
}

也就是說由於權限問題導致請求失敗,返回403錯誤。

針對這個問題,最主要的原因是:SpringSecrity默認開啓CSRF保護。

CSRF(Cross Site Request Forgery, 跨站域請求僞造)是一種網絡的攻擊方式。

可以這麼理解CSRF攻擊:攻擊者盜用了你的身份,以你的名義發送惡意請求。CSRF能夠做的事情包括:以你名義發送郵件,發消息,盜取你的賬號,甚至於購買商品,虛擬貨幣轉賬…造成的問題包括:個人隱私泄露以及財產安全。

那麼如何解決呢?方案有兩種:

方案一:簡單直接,禁用CSRF。修改之後的代碼如下:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.csrf().disable();
		http.authorizeRequests()
				.antMatchers("/api/**").permitAll() 
				.anyRequest().authenticated()
				.and()
				.formLogin()
				.permitAll();
	}
}

也就是添加了一行http.csrf().disable();。

方案二:重寫CSRF保護策略。示例代碼如下:

import org.springframework.security.web.util.matcher.RequestMatcher;
 
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
 
public class CsrfSecurityRequestMatcher implements RequestMatcher {
 
    private Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$");
 
    @Override
    public boolean matches(HttpServletRequest request) {
        List<String> unExecludeUrls = new ArrayList<>();
        //unExecludeUrls.add("/api/test");//(不允許post請求的url路徑)此處根據自己的需求做相應的邏輯處理
 
        if (unExecludeUrls != null && unExecludeUrls.size() > 0) {
            String servletPath = request.getServletPath();
            request.getParameter("");
            for (String url : unExecludeUrls) {
                if (servletPath.contains(url)) {
                    return true;
                }
            }
        }
        return allowedMethods.matcher(request.getMethod()).matches();
    }
}

經過以上兩種方案解決之後,錯誤也就消失了。
原文鏈接:《Spring Boot使用Spring Security POST無法訪問解決方案

精品SpringBoot 2.x視頻教程

《Spring Boot 2.x 視頻教程全家桶》,精品Spring Boot 2.x視頻教程,打造一套最全的Spring Boot 2.x視頻教程。


程序新視界

公衆號“程序新視界”,一個讓你軟實力、硬技術同步提升的平臺

csdn-微信公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章