暂存提交

This commit is contained in:
2026-07-30 18:01:36 +08:00
commit 2f4e159356
368 changed files with 20370 additions and 0 deletions
@@ -0,0 +1,89 @@
package com.baiyue.common.security;
import com.baiyue.common.core.mybatis.AuditorProvider;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* Servlet 服务安全自动配置,建立无状态 JWT 认证链、统一异常响应和审计操作者解析。
*/
@AutoConfiguration(
after = HmacJwtDecoderAutoConfiguration.class,
before = SecurityAutoConfiguration.class)
@EnableMethodSecurity
public class BaiyueSecurityAutoConfiguration {
@Bean
@ConditionalOnMissingBean
JwtClaimsMapper jwtClaimsMapper() { return new JwtClaimsMapper(); }
@Bean
@ConditionalOnMissingBean(AuthenticationEntryPoint.class)
AuthenticationEntryPoint jsonAuthenticationEntryPoint(ObjectMapper objectMapper) {
return new JsonAuthenticationEntryPoint(objectMapper);
}
@Bean
@ConditionalOnMissingBean(AccessDeniedHandler.class)
AccessDeniedHandler jsonAccessDeniedHandler(ObjectMapper objectMapper) {
return new JsonAccessDeniedHandler(objectMapper);
}
@Bean
@ConditionalOnMissingBean
JwtAuthenticationFilter jwtAuthenticationFilter(JwtDecoder jwtDecoder, JwtClaimsMapper claimsMapper,
AuthenticationEntryPoint entryPoint,
StringRedisTemplate redisTemplate,
@Value("${baiyue.security.token-key-prefix:baiyue:auth}") String keyPrefix) {
return new JwtAuthenticationFilter(jwtDecoder, claimsMapper, entryPoint,
new RedisAccessTokenSessionValidator(redisTemplate, keyPrefix));
}
@Bean
FilterRegistrationBean<JwtAuthenticationFilter> disableContainerRegistration(
JwtAuthenticationFilter filter) {
FilterRegistrationBean<JwtAuthenticationFilter> registration = new FilterRegistrationBean<>(filter);
registration.setEnabled(false);
return registration;
}
@Bean
@ConditionalOnMissingBean(SecurityFilterChain.class)
SecurityFilterChain baiyueSecurityFilterChain(
HttpSecurity http, JwtAuthenticationFilter jwtFilter,
AuthenticationEntryPoint entryPoint, AccessDeniedHandler deniedHandler) throws Exception {
return http
.csrf(csrf -> csrf.disable())
.httpBasic(httpBasic -> httpBasic.disable())
.formLogin(form -> form.disable())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.exceptionHandling(errors -> errors
.authenticationEntryPoint(entryPoint).accessDeniedHandler(deniedHandler))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/actuator/health", "/v3/api-docs/**", "/swagger-ui/**").permitAll()
.requestMatchers("/internal/**").permitAll()
.requestMatchers("/api/merchant/**").hasAuthority("APP_MERCHANT")
.requestMatchers("/api/platform/**").hasAuthority("APP_PLATFORM")
.anyRequest().authenticated())
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
.build();
}
@Bean
@Primary
AuditorProvider securityAuditorProvider() { return new SecurityAuditorProvider(); }
}