S SmartDocs
系列: Java java 62 行 · 更新于 2026-04-09

SecurityConfig.java

Java/Baasid/src/main/java/com/baasid/config/SecurityConfig.java

package com.baasid.config;

import com.baasid.security.JwtAuthenticationFilter;
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.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * Spring Security 設定:JWT 無狀態驗證、路徑授權、密碼雜湊演算法。
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final JwtAuthenticationFilter jwtAuthenticationFilter;

    public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter) {
        this.jwtAuthenticationFilter = jwtAuthenticationFilter;
    }

    /**
     * 定義 HTTP 安全規則與濾鏡順序。
     * <ul>
     *   <li>關閉 CSRF:REST API 使用 JWT,採用無狀態設計</li>
     *   <li>不使用 Session:{@link SessionCreationPolicy#STATELESS}</li>
     *   <li>登入與 Swagger 文件路徑允許匿名;其餘需已認證(由 JWT 濾鏡填入 {@code SecurityContext})</li>
     *   <li>在表單登入濾鏡之前執行 {@link JwtAuthenticationFilter},先解析 Bearer Token</li>
     * </ul>
     */
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable())
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authorizeHttpRequests(auth -> auth
                .requestMatchers(
                    "/auth/login",
                    "/swagger-ui/**",
                    "/swagger-ui.html",
                    "/v3/api-docs/**"
                ).permitAll()
                .anyRequest().authenticated()
            )
            .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

    /**
     * 密碼儲存前單向雜湊(登入時以 {@code matches} 比對明文與雜湊值)。
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

相关文章