
在現代 Web 開發中,安全性是一個不可忽視的重要議題
Spring Security 作為 Spring 生態系統中的一員,為開發者提供了一套強大且靈活的安全解決方案
讓我們一起來探索 Spring Security 的基礎知識,並了解如何在 Spring Boot 應用中實現基本的安全防護
Spring Security 是一個功能豐富的安全框架,專門用於保護以 Spring 為基礎的應用程式
它提供了全面的安全服務,包括身份驗證、授權、防護常見的 Web 攻擊等
可以利用 IDE 的功能,方便的加上 Spring Security 的依賴,預設會加上 security 和 security-test 這兩個依賴
如果是自己手動新增的話,就看需不需要加上 test 那個

implementation 'org.springframework.boot:spring-boot-starter-security'
// 方便你在測試使用的 spring-security-test
testImplementation 'org.springframework.security:spring-security-test'
安裝完 Spring Security 後,它會自動設定一些基本的安全設定
預設的情況之下是最安全的 (因為所有的端點都被保護),在視使用者的需要,一步步的打開 (設定) 安全性
安裝完後執行程式,應該可以在 log 中看到有關 Security 的相關訊息
產生了一個預設的密碼:3c24f6a4-bba8-4377-b3db-060ed6210976
開發使用不一樣 已經設定了一個全站的 AuthenticationManager,並且使了一個 inMemoryUserDetailsManager 的 UserDetailsService

Spring Security 提供了一個基本 (預設) 的登入頁面
當你存取任何受保護的資源 (頁面) 時,會自動導向到這個登入頁面

可以使用預設的帳號和密碼就可以登入
user log 裡面的預設密碼登入後在任一頁面查看 Cookie 的話,可以看到有一個 session cookie
它會記錄這次登入相關的資訊,把它刪掉的話,就會要求你登入了

如果使用先前的 api-test.http 來測試 API,就會出現 401 的狀況
在回應的訊息裡面也有 WWW-Authenticate: Base,基本上就是告訴你需要使用 HTTP Basic 認證
而 realm 是用來標識和區分不同的受保護區域,讓使用者和瀏覽器知道,他們正在存取哪個特定的安全區域
Realm 只是一個廣泛用的示例值

而下面這三個,是 Spring Security 預設的安全相關的 HTTP Header,用於防止各種常見的 Web 攻擊
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
X-Frame-Options: DENY
如果在 header 裡面有帶上 HTTP Basic 認證 的話,就可以拿到相對應的資料了

先建立一個 SecurityConfig,然後加上 EnableMethodSecurity 註解
EnableMethodSecurity 預設啟用了 @PreAuthorize、@PostAuthorize 、 @PreFilter 和 @PostFilter
@Configuration
@EnableMethodSecurity
public class SecurityConfig {
}
在 API 上面,可以使用 @PreAuthorize 註解來控制方法級別 (API) 的存取
以下面的 API 為例,角色必須是 ADMIN 才可以存取
而系統預設的使用者是沒有 Role 的
@RestController
public class HelloController {
@PreAuthorize("hasRole('ADMIN')")
@GetMapping("/api/hello")
public String hello() {
return "Hello from Spring Boot!";
}
}
直接使用預設的使用者呼叫 API 會取得 Access Denied

可以寫一個 API 來取得現在登入者的相關資訊,可以看到 Authorities (Role) 的部分是空的
@GetMapping("/authInfo")
public String authInfo(Authentication auth) {
return "Authentication type: " + auth.getClass().getSimpleName()
+ "\nName: " + auth.getName()
+ "\nAuthorities: " + auth.getAuthorities()
+ "\nDetails: " + auth.getDetails()
+ "\nCredentials: " + auth.getCredentials()
+ "\nPrincipal: " + auth.getPrincipal();
}

因為預設的使用者沒有 Role 可以設定
我們可以簡單的使用 application.properties 來做一些 Spring Security 的設定
下面我們設定了帳號、密碼和角色的部份
spring.security.user.name=cash
spring.security.user.password=abc123!
spring.security.user.roles=ADMIN
要注意的是,當你設定了
user的password的話,那程式就不會再自動產生一組預設的密碼了
設定好之後,再取得一次相關的登入者訊息,可以看到 Authorities 有 ROLE_ADMIN 了
Spring Security預設會給Role加上ROLE_的前綴不過在程式碼裡面,就只要寫
ADMIN就好了

再一次呼叫 API,就可以拿到資料了

Spring Security 為 Spring Boot 應用提供了強大的安全功能
通過簡單的設定,你就可以為你的應用程式添加基本的安全防護
隨著你對 Spring Security 的深入了解,你可以根據應用程式的具體需求進行更複雜的自訂設定
下一篇文章我們將更深入的討論 Spring Security 的自定義設定
同步刊登於 Blog 「Spring Boot API 開發:從 0 到 1」Day 32 Spring Security 基礎
我的粉絲專頁
圖片來源:AI 產生