You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

68 lines
3.0 KiB

package com.crm.auth.config;
import com.crm.auth.security.JwtAuthenticationFilter;
import com.crm.auth.security.SecurityExceptionHandlers;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
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.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* Spring Security 配置:无状态 JWT 模式
* <p>依赖了 crm-auth 的业务模块自动获得本配置(登录接口 + token 校验 + 401/403 JSON 返回)</p>
*/
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfig {
/**
* 默认放行路径;业务模块如需追加,配置 crm.auth.ignore-urls
*/
private static final String[] DEFAULT_IGNORE_URLS = {
// 登录接口
"/api/auth/login/**",
// 接口文档
"/doc.html",
"/webjars/**",
"/v3/api-docs/**",
"/swagger-ui/**",
"/swagger-resources/**",
// 其他
"/favicon.ico",
"/error",
};
private final JwtAuthenticationFilter jwtAuthenticationFilter;
private final SecurityExceptionHandlers securityExceptionHandlers;
private final AuthProperties authProperties;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// JWT 无状态,关闭 csrf 和 session
.csrf(csrf -> csrf.disable())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> {
auth.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.requestMatchers(DEFAULT_IGNORE_URLS).permitAll();
// 业务模块通过 crm.auth.ignore-urls 追加的放行路径
if (!authProperties.getIgnoreUrls().isEmpty()) {
auth.requestMatchers(authProperties.getIgnoreUrls().toArray(String[]::new)).permitAll();
}
auth.anyRequest().authenticated();
})
.exceptionHandling(handler -> handler
.authenticationEntryPoint(securityExceptionHandlers)
.accessDeniedHandler(securityExceptionHandlers))
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}