SpringSecurity - [01] 概述

HOUHUILIN發表於2024-12-05

Spring Security 是一個靈活且強大的工具,可以幫助你構建安全可靠的Spring應用程式。它不僅簡化了認證和授權的過程,而且還提供了豐富的特性和擴充套件點,使得開發者可以根據專案的獨特需求定製安全策略。無論是小型的內部工具還是大型的企業級應用,Spring Security都能提供必要的安全保障。

001 || SpringSecurity是什麼

Spring Security是一個強大的、可定製的身份驗證和訪問控制框架,它是為基於Java的Spring應用程式設計的安全框架。

它提供了全面的安全服務,包括不限於:

  • 認證(Authentication):確認使用者身份,即驗證使用者提供的憑證(如使用者名稱和密碼)是否正確。
  • 授權(Authorization):決定已認證的使用者是否有許可權執行某些操作或訪問特定資源。

Spring Security構建在Spring框架之上,可以輕鬆整合到任何基於Spring的應用程式中,並且支援多種安全協議和技術,如OAuth2、JWT(JSON Web Tokens)、LDAP等。

002 || 作用

【1】保護Web應用:透過配置HTTP請求的安全策略來保護Web應用程式,例如限制對某些URL的訪問。

【2】管理使用者認證:提供多種方式來處理使用者登入,包括表單登入、基本認證、記住我功能等。

【3】實施訪問控制:允許開發者定義細粒度的訪問規則,以確保只有授權使用者才能訪問敏感資料或執行關鍵操作。

【4】防止常見的共計:內建防禦機制對抗跨站指令碼共計(XSS)、跨站請求偽造(CSRF)、點選劫持(Clickjacking)等常見安全威脅。

【5】支援多樣的認證機制:除了傳統的使用者名稱/密碼認證外,還支援社交登入(如Google、Facebook)、雙因素認證等現代認證方式。

003 || 如何使用

要在Spring Boot專案中使用Spring Security,通常需要完成以下幾個步驟:

(1)新增依賴

首先,在pom.xmlbuild.gradle檔案中新增Spring Security Starter依賴。以Maven專案為例,則為:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

(2)配置安全性

可以透過Java配置類或YAML/Properties檔案來進行Spring Security相關配置。

下面是一個簡單的Java配置示例,它允許匿名訪問/hello路徑,而其他所有請求都需要認證。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/hello").permitAll() // 允許所有人訪問 /hello
                .anyRequest().authenticated()     // 所有其他請求都需要認證
            .and()
            .formLogin();                         // 啟用表單登入
        return http.build();
    }
}

(3)建立使用者詳情服務(可選)

自定義使用者儲存和服務,比如從資料庫載入使用者資訊,需要實現UserDetailsService介面並覆蓋loadUserByUsername方法。然後將這個實現註冊為SpringBean

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 根據使用者名稱查詢使用者實體,並將其轉換為Spring Security的UserDetails物件
        return userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found"));
    }
}

(4)定義使用者和角色(可選)

透過記憶體中的使用者配置快速設定一些測試使用者及其角色。這對於開發階段非常有用:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class SecurityConfiguration {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user").password(passwordEncoder().encode("password")).roles("USER")
            .and()
            .withUser("admin").password(passwordEncoder().encode("admin")).roles("ADMIN");
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

(5)自定義登入頁面(可選)

預設情況下,Spring Security會提供一個簡易的登入頁面。如果想要建立自己的登入介面,可以透過覆蓋預設的登入路徑來實現:

http
    .formLogin()
        .loginPage("/login")  // 指定自定義登入頁面的URL
        .permitAll();         // 允許所有人訪問登入頁面

同時,需要建立相應的HTML模板或者JSP頁面用於顯示登入表單。

相關文章