在《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視頻教程。