Files
demo/src/main/java/com/mikufufu/config/SecurityConfig.java
蔡浩珊_信息数字化部 f053037227 first commit
2026-05-23 17:20:26 +08:00

166 lines
7.7 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.mikufufu.config;
import com.mikufufu.modules.auth.security.filter.IllegalRequestFilter;
import com.mikufufu.modules.auth.security.filter.TokenFilter;
import com.mikufufu.modules.auth.security.handler.AuthorizationManagerImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Stream;
/**
* Spring Security配置类
*
*/
@Slf4j
@Configuration // 表示这是一个配置类
@EnableWebSecurity // 启用Spring Web安全功能
@EnableMethodSecurity
public class SecurityConfig {
/**
* 认证失败处理类:用于处理认证失败的情况。
*/
@Autowired
private AuthenticationEntryPoint authenticationEntryPoint;
/**
* 权限拒绝处理类:用于处理没有权限访问的情况。
*/
@Autowired
private AccessDeniedHandler accessDeniedHandler;
// 解决循环依赖的问题
@Bean
public AuthorizationManager<RequestAuthorizationContext> authorizationManager(){
return new AuthorizationManagerImpl();
}
/**
* 获取匿名访问的权限列表。
* 匿名权限即不需要用户登录即可访问的资源路径。
*
* @return 返回一个包含所有匿名权限路径的列表。
*/
private String[] anonymousGet(){
// 初始化匿名权限路径列表包括默认权限、Swagger文档权限
String[] defaultPermission = {"/cache/**","/logout"};
String[] swaggerPermission = {"/doc.html","/swagger-resources/**","/webjars/**","/v3/api-docs/**","/swagger-ui/**"};
// 合并权限列表,去除重复项
return Stream.of(defaultPermission, swaggerPermission)
.flatMap(Arrays::stream).distinct()
.toArray(String[]::new);
}
/**
* 静态资源路径
* 解决 ** 路径无法匹配的问题
* @return AntPathRequestMatcher[]
*/
private AntPathRequestMatcher[] staticResources(){
String[] staticPath = {"/","/*.html","/**/*.html","/**/*.js","/**/*.css","/favicon.ico","/image/**"};
// 创建一个AntPathRequestMatcher数组用于匹配静态资源路径
AntPathRequestMatcher[] antPathRequestMatchers = new AntPathRequestMatcher[staticPath.length];
// 遍历静态资源路径数组为每个路径创建一个AntPathRequestMatcher对象
for (int i = 0; i < staticPath.length; i++) {
antPathRequestMatchers[i] = new AntPathRequestMatcher(staticPath[i]);
}
// 返回AntPathRequestMatcher数组
return antPathRequestMatchers;
}
/**
* 配置CORS跨源资源共享设置以允许来自特定源的Web请求访问应用程序。
* 这个方法返回一个CorsConfigurationSource实例其中包含了对跨域请求的配置。
* @return UrlBasedCorsConfigurationSource 一个基于URL的CORS配置源用于指定哪些URL路径应用此CORS配置。
*/
@Bean
public CorsConfigurationSource configurationSource(){
// 创建一个新的CORS配置对象
CorsConfiguration corsConfiguration = new CorsConfiguration();
// 设置允许的所有请求头
corsConfiguration.setAllowedHeaders(Collections.singletonList("*"));
// 设置允许的所有请求方法
corsConfiguration.setAllowedMethods(Collections.singletonList("*"));
// 设置允许的请求来源,这里指定了两个来源:本地开发环境和一个示例域名
// corsConfiguration.setAllowedOrigins(Arrays.asList("http://localhost:8080","https://www.mikufufu.com"));
corsConfiguration.addAllowedOrigin("*");
// 设置预检请求OPTIONS请求的缓存时间单位为秒
corsConfiguration.setMaxAge(3600L);
// 创建一个新的URL基于的CORS配置源
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
// 将之前配置的CORS配置应用到所有URL路径
source.registerCorsConfiguration("/**",corsConfiguration);
// 返回配置源
return source;
}
/**
* 配置安全过滤链
* @param http 用于配置HttpSecurity的bean
* @return 返回配置好的SecurityFilterChain
* @throws Exception 配置过程中可能抛出的异常
*/
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// 配置CORS跨域资源共享
.cors(cors -> cors.configurationSource(configurationSource()))
// 禁用CSRF保护
.csrf(AbstractHttpConfigurer::disable)
// 禁用会话创建
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
// 禁用security默认的注销接口以解决重定向到login页面时因为没有登录所以会重定向到登录页面但是登录页面没有权限所以会抛出异常。
.logout(AbstractHttpConfigurer::disable)
// 配置请求过滤规则
.authorizeHttpRequests(authorize -> authorize
// 放行静态资源
.requestMatchers(staticResources()).permitAll()
// 允许GET请求和POST请求
.requestMatchers(HttpMethod.GET, anonymousGet()).permitAll()
.requestMatchers(HttpMethod.POST, "/login","/admin/login","/register").permitAll()
// 使用自定义的权限管理器进行权限检查
.anyRequest().access(authorizationManager())
)
.addFilterBefore(new TokenFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new IllegalRequestFilter(),TokenFilter.class);
// 允许iframe访问
http.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable));
http.exceptionHandling(exceptionHandling ->
exceptionHandling
// 认证失败处理
.authenticationEntryPoint(authenticationEntryPoint)
// 权限不足处理
.accessDeniedHandler(accessDeniedHandler));
// 构建并返回安全过滤链
return http.build();
}
}