package com.test.bijihoudaun.config; import com.test.bijihoudaun.config.security.JwtAccessDeniedHandler; import com.test.bijihoudaun.config.security.JwtAuthenticationEntryPoint; import com.test.bijihoudaun.interceptor.JwtAuthenticationTokenFilter; import com.test.bijihoudaun.util.JwtTokenUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; 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.core.userdetails.UserDetailsService; 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; @Configuration @EnableWebSecurity public class SecurityConfig { @Autowired private UserDetailsService userDetailsService; @Autowired private JwtTokenUtil jwtTokenUtil; @Autowired private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; @Autowired private JwtAccessDeniedHandler jwtAccessDeniedHandler; @Value("${jwt.header}") private String tokenHeader; @Value("${jwt.tokenHead}") private String tokenHead; // 配置了密码编码器 @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } // 配置了安全过滤器链 @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter = new JwtAuthenticationTokenFilter(userDetailsService, jwtTokenUtil, tokenHeader, tokenHead); http .csrf(csrf -> csrf.disable()) // 配置了 CSRF 禁用、无状态会话管理 .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(authz -> authz // 1. 始终允许的核心公共端点 (登录、注册、API文档) .requestMatchers( "/doc.html", "/webjars/**", "/v3/api-docs/**", "/api/user/login", "/api/user/register" ).permitAll() // 2. 精确允许用于“公开阅读”的 GET 请求 .requestMatchers(org.springframework.http.HttpMethod.GET, "/api/groupings/**", // 获取分组 "/api/images/preview/**", // 预览图片 "/api/markdown/files", // 获取所有文件 "/api/markdown/search", // 搜索文件 "/api/markdown/grouping/**", // 按分组获取文件 "/api/markdown/recent", // 获取最近文件 "/api/markdown/{id}", // 获取单个文件内容 "/api/system/registration/status" // 检查注册是否开启 ).permitAll() // 3. 除上述白名单外,所有其他请求都需要认证 .anyRequest().authenticated() ) // 添加自定义的异常处理器 .exceptionHandling(exceptions -> exceptions .authenticationEntryPoint(jwtAuthenticationEntryPoint) .accessDeniedHandler(jwtAccessDeniedHandler) ); // 在这里添加JWT过滤器 http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); } }