如何解決 Spring Boot POST 請求中的 403 錯誤
1. 概述
在 Web 開發中遇到錯誤是很常見的事情。 HTTP 403 禁止錯誤就是此類錯誤之一。
在本教程中,我們將學習如何解決 Spring Boot POST 請求中的 403 錯誤。我們將首先了解 403 錯誤的含義,然後探索在 Spring Boot 應用程序中解決該錯誤的步驟。
2. 403錯誤是什麼?
HTTP 403 錯誤通常稱為“ Forbidden
”錯誤,是一種狀態代碼,表示服務器理解該請求,但選擇不授權該請求。這通常意味著客戶端缺乏訪問所請求資源的權限。
需要注意的是,此錯誤與 401 錯誤不同,401 錯誤表示服務器需要對客戶端進行身份驗證,但尚未收到有效憑據。
三、403錯誤原因
有多種因素可能會在 Spring Boot 應用程序中觸發 403 錯誤。其中之一是客戶端無法提供身份驗證憑據。在這種情況下,服務器無法驗證客戶端的權限,因此會拒絕請求,從而導致 403 錯誤。
另一個可能的原因在於服務器配置。例如,作為安全措施,服務器可以配置為拒絕來自某些 IP 地址或用戶代理的請求。如果請求源自這些被阻止的實體,服務器將返回 403 錯誤
此外,Spring Security 默認啟用跨站點請求偽造(CSRF)保護。 CSRF 是一種欺騙受害者提交惡意請求並使用受害者的身份代表他們執行不需要的功能的攻擊。如果用於防範此類攻擊的 CSRF 令牌丟失或不正確,服務器也可能會響應錯誤 403 。
4. 項目設置
要了解如何解決 403 錯誤,讓我們使用spring-boot-starter-web和spring-boot-starter-security依賴項創建一個 Spring Boot 項目:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
接下來,讓我們創建一個控制器類來處理 POST 請求:
@PostMapping("/test-request")
public ResponseEntity<String> testPostRequest() {
return ResponseEntity.ok("POST request successful");
}
上面的方法有@PostMapping
註解,這意味著它可以處理對服務器的POST請求。成功的 POST 請求將返回“ POST request successful
”作為響應。
接下來,讓我們通過添加內存用戶來配置 Spring Security:
@Bean
public InMemoryUserDetailsManager userDetailsService() {
UserDetails user = User.withUsername("user")
.password(encoder().encode("userPass"))
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
在上面的代碼中,我們將應用程序配置為使用內存中的用戶進行請求身份驗證。用戶的密碼使用BCryptPasswordEncoder
進行編碼以增強安全性。
此外,讓我們配置SecurityFilterChain
以接受所有傳入請求:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests(authorizeRequests -> authorizeRequests.anyRequest()
.permitAll());
return http.build();
}
在這段代碼中,我們將應用程序配置為允許所有傳入請求,而不需要任何形式的身份驗證。
5.解決Spring Boot POST請求中的403錯誤
在本節中,我們將探討可能導致錯誤 403 的幾個因素並討論可能的解決方案。
5.1.跨站點請求偽造 (CSRF) 保護
默認情況下,Spring Security 啟用 CSRF 保護。如果請求標頭中缺少 CRSF 令牌,服務器將響應 403 錯誤。此行為並不特定於任何服務器環境,包括本地主機、登台或生產。
讓我們嘗試發出 POST 請求:
$ curl -X POST -H "Content-Type: application/json" http://localhost:8080/test-request
上述請求會導致禁止錯誤:
{"timestamp":"2023-06-24T16:52:05.397+00:00","status":403,"error":"Forbidden","path":"/test-request"}
我們可以通過禁用 CSRF 保護來解決此錯誤:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests(authorizeRequests -> authorizeRequests.anyRequest()
.permitAll())
.csrf(AbstractHttpConfigurer::disable);
return http.build();
}
在上面的代碼中,我們通過調用disable()
方法禁用CSRF保護。
讓我們向“ /test-request
”端點發出 POST 請求:
$ curl -X POST -H "Content-Type: application/json" http://localhost:8080/test-request
禁用 CRSF 後,我們發出 POST 請求,服務器響應預期的 HTTP 響應“ POST request successful
”。
但是,需要注意的是,通常不建議在生產應用程序中禁用 CRSF 保護。 CRSF 保護是防止跨站偽造攻擊的重要安全措施。因此,建議將 CRSF 令牌包含在狀態更改操作的請求標頭中。
5.2.認證憑證
提供不正確的身份驗證憑據或不向安全端點提供身份驗證憑據可能會導致 Spring Boot 應用程序中出現 403 錯誤。
讓我們修改SecurityFilterChain
以驗證對服務器的所有請求:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests(authorizeRequests -> authorizeRequests.anyRequest()
.authenticated())
.httpBasic(withDefaults())
.formLogin(withDefaults())
.csrf(AbstractHttpConfigurer::disable);
return http.build();
}
在上面的代碼中,我們將應用程序配置為在授予訪問權限之前對每個請求進行身份驗證。如果我們向端點發出 POST 請求而未提供正確的身份驗證憑據,服務器將返回 403 錯誤。
讓我們使用我們創建的內存用戶的憑據向“ /test-request
”端點發出 POST 請求:
上圖顯示,當我們提供正確的身份驗證時,服務器會響應 200 OK 狀態代碼。
六,結論
在本文中,我們學習瞭如何通過禁用 CRSF 保護並提供正確的身份驗證憑據來解決 Spring Boot 中的 403 錯誤。我們還了解瞭如何配置 Spring Security 以接受經過身份驗證和未經身份驗證的請求。此外,我們還重點介紹了 Spring Boot 應用程序出現 403 錯誤的不同原因。
與往常一樣,示例的完整源代碼可在 GitHub 上獲取。