From b2fff8ec8a0ead11259169b8648bd97abdb64665 Mon Sep 17 00:00:00 2001 From: dengqichen Date: Tue, 9 Dec 2025 18:07:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9LIQUIBASE=E7=9A=84=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../security/config/SecurityConfig.java | 14 +++-------- .../config/SecurityWhitelistProperties.java | 25 +++++++++++++++++++ .../filter/JwtAuthenticationFilter.java | 14 +++-------- .../src/main/resources/application-prod.yml | 12 +++++++++ backend/src/main/resources/application.yml | 12 +++++++++ .../db/changelog/sql/20251209141300-01.sql | 22 ++++++++++------ 6 files changed, 70 insertions(+), 29 deletions(-) create mode 100644 backend/src/main/java/com/qqchen/deploy/backend/framework/security/config/SecurityWhitelistProperties.java diff --git a/backend/src/main/java/com/qqchen/deploy/backend/framework/security/config/SecurityConfig.java b/backend/src/main/java/com/qqchen/deploy/backend/framework/security/config/SecurityConfig.java index a988cadd..1d962266 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/framework/security/config/SecurityConfig.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/framework/security/config/SecurityConfig.java @@ -27,6 +27,7 @@ public class SecurityConfig { private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint; private final JwtTokenUtil jwtTokenUtil; private final UserDetailsService userDetailsService; + private final SecurityWhitelistProperties whitelistProperties; @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { @@ -37,15 +38,8 @@ public class SecurityConfig { session.sessionCreationPolicy(SessionCreationPolicy.STATELESS) ) .authorizeHttpRequests(auth -> auth - .requestMatchers( - "/api/v1/user/login", - "/api/v1/user/register", - "/api/v1/tenant/list", - "/api/v1/server-ssh/*/files/**", - "/swagger-ui/**", - "/v3/api-docs/**", - "/actuator/health" - ).permitAll() + .requestMatchers(whitelistProperties.getPaths().toArray(new String[0])) + .permitAll() .anyRequest().authenticated() ) .addFilterBefore( @@ -61,7 +55,7 @@ public class SecurityConfig { @Bean public JwtAuthenticationFilter jwtAuthenticationFilter() { - return new JwtAuthenticationFilter(jwtTokenUtil, userDetailsService); + return new JwtAuthenticationFilter(jwtTokenUtil, userDetailsService, whitelistProperties); } @Bean diff --git a/backend/src/main/java/com/qqchen/deploy/backend/framework/security/config/SecurityWhitelistProperties.java b/backend/src/main/java/com/qqchen/deploy/backend/framework/security/config/SecurityWhitelistProperties.java new file mode 100644 index 00000000..8271466d --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/framework/security/config/SecurityWhitelistProperties.java @@ -0,0 +1,25 @@ +package com.qqchen.deploy.backend.framework.security.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +/** + * Security 白名单配置属性 + * + * @author qqchen + * @since 2025-12-09 + */ +@Data +@Component +@ConfigurationProperties(prefix = "security.whitelist") +public class SecurityWhitelistProperties { + + /** + * 免认证路径列表 + */ + private List paths = new ArrayList<>(); +} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/framework/security/filter/JwtAuthenticationFilter.java b/backend/src/main/java/com/qqchen/deploy/backend/framework/security/filter/JwtAuthenticationFilter.java index 322fa06e..301c99a4 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/framework/security/filter/JwtAuthenticationFilter.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/framework/security/filter/JwtAuthenticationFilter.java @@ -7,6 +7,7 @@ import com.qqchen.deploy.backend.framework.enums.ResponseCode; import com.qqchen.deploy.backend.framework.exception.BusinessException; import com.qqchen.deploy.backend.framework.exception.JwtAuthenticationException; import com.qqchen.deploy.backend.framework.exception.SystemException; +import com.qqchen.deploy.backend.framework.security.config.SecurityWhitelistProperties; import com.qqchen.deploy.backend.framework.security.util.JwtTokenUtil; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.MalformedJwtException; @@ -27,8 +28,6 @@ import org.springframework.web.filter.OncePerRequestFilter; import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.List; @Slf4j @RequiredArgsConstructor @@ -38,19 +37,12 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { private final UserDetailsService userDetailsService; - private static final List WHITELIST = Arrays.asList( - "/api/v1/user/login", - "/api/v1/user/register", - "/api/v1/tenant/list", - "/swagger-ui/**", - "/v3/api-docs/**", - "/actuator/health" - ); + private final SecurityWhitelistProperties whitelistProperties; @Override protected boolean shouldNotFilter(HttpServletRequest request) { String path = request.getServletPath(); - return WHITELIST.stream().anyMatch(path::startsWith); + return whitelistProperties.getPaths().stream().anyMatch(path::startsWith); } @Override diff --git a/backend/src/main/resources/application-prod.yml b/backend/src/main/resources/application-prod.yml index 2ffa4f1f..d4b5bc87 100644 --- a/backend/src/main/resources/application-prod.yml +++ b/backend/src/main/resources/application-prod.yml @@ -149,6 +149,18 @@ jwt: secret: 'thisIsAVeryVerySecretKeyForJwtTokenGenerationAndValidation123456789' expiration: 86400 +# Security 白名单配置 +security: + whitelist: + paths: + - /api/v1/user/login + - /api/v1/user/register + - /api/v1/tenant/list + - /api/v1/server-ssh/*/files/** + - /swagger-ui/** + - /v3/api-docs/** + - /actuator/** + jackson: time-zone: Asia/Shanghai diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index d16cdfb2..35600e8d 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -145,6 +145,18 @@ jwt: secret: 'thisIsAVeryVerySecretKeyForJwtTokenGenerationAndValidation123456789' expiration: 86400 +# Security 白名单配置 +security: + whitelist: + paths: + - /api/v1/user/login + - /api/v1/user/register + - /api/v1/tenant/list + - /api/v1/server-ssh/*/files/** + - /swagger-ui/** + - /v3/api-docs/** + - /actuator/** + jackson: time-zone: Asia/Shanghai diff --git a/backend/src/main/resources/db/changelog/sql/20251209141300-01.sql b/backend/src/main/resources/db/changelog/sql/20251209141300-01.sql index c7d9a1f5..bcad202c 100644 --- a/backend/src/main/resources/db/changelog/sql/20251209141300-01.sql +++ b/backend/src/main/resources/db/changelog/sql/20251209141300-01.sql @@ -14,14 +14,20 @@ VALUES ( 'system', NOW(), 'system', NOW(), 1, 0, 1.12, 'ALL', NOW(), '【后端】 -- 优化:生产环境日志级别(空结果/开始日志/详细过程调整为DEBUG,减少冗余输出) -- 优化:HikariCP连接泄漏检测阈值(调整为35分钟,匹配Jenkins构建轮询时长) -- 优化:SSHJ底层日志屏蔽(Transport/SecureRandom等无业务价值日志降级为WARN) -- 优化:服务器连接状态日志(提升连接成功日志为INFO,便于生产监控) -- 优化:Liquibase配置(includeAll只扫描XML文件,避免SQL重复执行) -- 新增:系统指标监控菜单(实时查看JVM、CPU、内存、线程、连接池等性能指标) -- 新增:Actuator监控端点(threaddump/heapdump/env/loggers,支持动态调整日志级别) -- 数据:新增用户lukuan及角色绑定(深圳部门/开发角色) +- 日志优化:生产环境日志级别调整(空结果/开始/详细过程→DEBUG,减少冗余输出) +- 连接池优化:HikariCP泄漏检测阈值调整为35分钟(匹配Jenkins构建轮询时长) +- SSH日志优化:SSHJ底层日志降级为WARN(屏蔽Transport/SecureRandom等无业务价值日志) +- 监控日志优化:服务器连接成功日志提升为INFO(便于生产环境状态监控) +- Liquibase优化:目录结构调整(XML/SQL分离,changes/只放XML,sql/只放SQL,避免重复执行) +- Security优化:白名单配置化(SecurityConfig/JwtAuthenticationFilter统一使用配置文件管理免认证路径) +- 系统监控:新增"系统指标"菜单(实时查看JVM、CPU、内存、线程、连接池等性能指标) +- Actuator集成:开放监控端点(health/metrics/threaddump/heapdump/env/loggers,支持动态调整日志级别) +- 配置管理:新增SecurityWhitelistProperties配置类(集中管理Security白名单,支持环境差异化配置) +【前端】 +- 新增:系统指标监控页面(实时监控JVM内存、CPU、线程、连接池、GC,30秒自动刷新) +- 新增:线程分析工具(状态筛选、智能排序、堆栈展开、问题线程识别、一键导出含堆栈) +- 优化:内存单位统一为GB(图表、趋势图、卡片全局一致,清理历史数据) +- 修复:Actuator接口代理和调用方式(新增/actuator代理配置) ', 0, NULL, NULL, 0 );