feat(framework): 添加Redis序列化白名单配置功能

This commit is contained in:
2026-01-24 09:48:18 +08:00
parent a4258a3851
commit 9b61ab35b6
23 changed files with 130 additions and 597 deletions
@@ -22,6 +22,7 @@ import cn.odboy.framework.properties.model.StorageOSSModel;
import cn.odboy.framework.properties.model.SwaggerApiDocSettingModel;
import cn.odboy.framework.properties.model.ThreadPoolSettingModel;
import cn.odboy.framework.properties.model.UserLoginSettingModel;
import java.util.List;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@@ -44,4 +45,8 @@ public class AppProperties {
private ThreadPoolSettingModel asyncTaskPool;
private CaptchaModel captcha;
private StorageOSSModel oss;
/**
* 自动识别json对象白名单配置(仅允许解析的包名, 范围越小越安全)<br/> 未配置可能导致, 登录失败, 反复登录等问题
*/
private List<String> serialWhiteList;
}
@@ -15,6 +15,7 @@
*/
package cn.odboy.framework.redis;
import cn.odboy.framework.properties.AppProperties;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONFactory;
import com.alibaba.fastjson2.JSONWriter;
@@ -25,6 +26,7 @@ import java.util.Map;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.MurmurHash3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.cache.Cache;
@@ -50,17 +52,8 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
@AutoConfigureBefore(RedisAutoConfiguration.class)
public class RedisConfiguration extends CachingConfigurerSupport {
/**
* 自动识别json对象白名单配置(仅允许解析的包名, 范围越小越安全)<br/> 未配置可能导致, 登录失败, 反复登录等问题
*/
private static final String[] WHITELIST_STR =
{
"org.springframework",
"cn.odboy.system.dal.dataobject",
"cn.odboy.system.dal.model",
"cn.odboy.task.dal.dataobject",
"cn.odboy.task.dal.model",
};
@Autowired
private AppProperties properties;
/**
* 设置 redis 数据默认过期时间,默认2小时 设置@cacheable 序列化方式
@@ -83,8 +76,9 @@ public class RedisConfiguration extends CachingConfigurerSupport {
template.setValueSerializer(fastJsonRedisSerializer);
template.setHashValueSerializer(fastJsonRedisSerializer);
// 设置fastJson的序列化白名单
for (String pack : WHITELIST_STR) {
for (String pack : properties.getSerialWhiteList()) {
JSONFactory.getDefaultObjectReaderProvider().addAutoTypeAccept(pack);
log.warn("设置fastJson的序列化白名单:{}", pack);
}
// key的序列化采用StringRedisSerializer
template.setKeySerializer(new StringRedisSerializer());
+4 -2
View File
@@ -9,13 +9,15 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>cutejava-starter</artifactId>
<name>启动模块</name>
<dependencies>
<dependency>
<groupId>cn.odboy</groupId>
<artifactId>cutejava-module-task-v1</artifactId>
<artifactId>cutejava-module-system</artifactId>
<version>1.5.2</version>
</dependency>
</dependencies>
<!-- 打包 -->
<build>
<!-- 和应用名一致 -->
@@ -35,4 +37,4 @@
</plugin>
</plugins>
</build>
</project>
</project>
@@ -51,7 +51,7 @@ spring:
db-type: com.alibaba.druid.pool.DruidDataSource
# sql监控
driverClassName: com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:mysql://127.0.0.1:23306/cutejava?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true
url: jdbc:p6spy:mysql://127.0.0.1:3306/cutejava?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true
username: root
password: kd123456
# 初始连接数,建议设置为与最小空闲连接数相同
@@ -105,9 +105,9 @@ spring:
multi-statement-allow: true
aop-patterns: "cn.odboy.mapper.*,cn.odboy.service.*,cn.odboy.*.mapper.*,cn.odboy.*.service.*"
redis:
database: ${REDIS_DB:1}
database: ${REDIS_DB:10}
host: ${REDIS_HOST:127.0.0.1}
port: ${REDIS_PORT:26379}
port: ${REDIS_PORT:6379}
password: ${REDIS_PWD:kd123456}
# 连接超时时间
timeout: 5000
@@ -211,6 +211,13 @@ app:
secretKey: 8BiK5UbmvXGJNVQ98CGiohHzT1N1FMRZqHRdJllj
captcha:
expireTime: 300
# 序列化白名单
serial-white-list:
- "org.springframework"
- "cn.odboy.system.dal.dataobject"
- "cn.odboy.system.dal.model"
- "cn.odboy.task.dal.dataobject"
- "cn.odboy.task.dal.model"
# debug
#debug: true
# 日志配置
@@ -50,7 +50,7 @@ spring:
druid:
db-type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.100.128:23306/cutejava?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true
url: jdbc:mysql://127.0.0.1:3306/cutejava?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true
username: root
password: kd123456
# 初始连接数,建议设置为与最小空闲连接数相同
@@ -105,8 +105,8 @@ spring:
aop-patterns: "cn.odboy.mapper.*,cn.odboy.service.*,cn.odboy.*.mapper.*,cn.odboy.*.service.*"
redis:
database: ${REDIS_DB:1}
host: ${REDIS_HOST:192.168.100.128}
port: ${REDIS_PORT:26379}
host: ${REDIS_HOST:127.0.0.1}
port: ${REDIS_PORT:6379}
password: ${REDIS_PWD:kd123456}
# 连接超时时间
timeout: 5000
@@ -210,6 +210,13 @@ app:
secretKey: 8BiK5UbmvXGJNVQ98CGiohHzT1N1FMRZqHRdJllj
captcha:
expireTime: 300
# 序列化白名单
serial-white-list:
- "org.springframework"
- "cn.odboy.system.dal.dataobject"
- "cn.odboy.system.dal.model"
- "cn.odboy.task.dal.dataobject"
- "cn.odboy.task.dal.model"
# debug
#debug: true
# 日志配置
@@ -1,44 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds" debug="false">
<contextName>CuteJava</contextName>
<property name="log.name" value="cutejava"/>
<property name="log.home" value="/var/logs"/>
<property name="log.charset" value="utf-8"/>
<property name="log.pattern"
value="%red(%contextName) - %red(%d{yyyy-MM-dd HH:mm:ss.SSS}) - %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}) - %msg%n"/>
<!-- Spring 日志级别控制 -->
<logger name="org.springframework" level="warn"/>
<!-- DnsServerAddressStreamProviders调整为ERROR -->
<logger name="io.netty.resolver.dns.DnsServerAddressStreamProviders" level="ERROR"/>
<!-- 设置其他类的日志级别为 ERROR -->
<logger name="org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]" level="ERROR"/>
<logger name="org.springframework.web.servlet.DispatcherServlet" level="ERROR"/>
<!--输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${log.pattern}</pattern>
<charset>${log.charset}</charset>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${log.home}/${log.name}.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.home}/${log.name}.log.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>90</maxHistory>
<maxFileSize>100MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<root level="INFO">
<!--普通日志输出到控制台-->
<appender-ref ref="CONSOLE"/>
<!--普通日志输出到文件-->
<appender-ref ref="FILE"/>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds" debug="false">
<contextName>CuteJava</contextName>
<property name="log.name" value="cutejava"/>
<property name="log.home" value="/var/logs"/>
<property name="log.charset" value="utf-8"/>
<property name="log.pattern"
value="%red(%contextName) - %red(%d{yyyy-MM-dd HH:mm:ss.SSS}) - %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}) - %msg%n"/>
<!-- Spring 日志级别控制 -->
<logger name="org.springframework" level="warn"/>
<!-- DnsServerAddressStreamProviders调整为ERROR -->
<logger name="io.netty.resolver.dns.DnsServerAddressStreamProviders" level="ERROR"/>
<!-- 设置其他类的日志级别为 ERROR -->
<logger name="org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]" level="ERROR"/>
<logger name="org.springframework.web.servlet.DispatcherServlet" level="ERROR"/>
<!--输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${log.pattern}</pattern>
<charset>${log.charset}</charset>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${log.home}/${log.name}.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.home}/${log.name}.log.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>90</maxHistory>
<maxFileSize>100MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<root level="INFO">
<!--普通日志输出到控制台-->
<appender-ref ref="CONSOLE"/>
<!--普通日志输出到文件-->
<appender-ref ref="FILE"/>
</root>
</configuration>
@@ -18,8 +18,6 @@ package cn.odboy.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
@@ -45,12 +43,6 @@ public class KitStringUtilTest {
assertEquals("\u0000_a", KitStringUtil.toUnderScoreCase("\u0000A"));
}
@Test
public void testGetWeekDay() {
SimpleDateFormat simpleDateformat = new SimpleDateFormat("E");
assertEquals(simpleDateformat.format(new Date()), KitStringUtil.getWeekDay());
}
@Test
public void testGetIP() {
Assertions.assertEquals("127.0.0.1", KitBrowserUtil.getIp(new MockHttpServletRequest()));