提交
This commit is contained in:
1 parent
623f5b65e7
commit
103a53f6f3
3 files changed
+58
-6
No files matched your search
+16
-3
@@ -2,9 +2,11 @@ package org.dromara.common.redis.config;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
|
||||
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
|
||||
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||
@@ -51,8 +53,19 @@ public class RedisConfig {
|
||||
om.registerModule(javaTimeModule);
|
||||
om.setTimeZone(TimeZone.getDefault());
|
||||
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
// 指定序列化输入的类型,类必须是非final修饰的。序列化时将对象全类名一起保存下来
|
||||
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
|
||||
// 使用包名白名单替代 LaissezFaireSubTypeValidator,降低 Redis 被写入恶意 @class 时的反序列化 RCE 风险
|
||||
// 说明:RedisUtils/Sa-Token 以 Object 读写缓存,仍需保留类型信息;禁止完全放开任意类反序列化
|
||||
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder()
|
||||
.allowIfSubType("org.dromara.")
|
||||
.allowIfSubType("cn.dev33.satoken.")
|
||||
.allowIfSubType("cn.hutool.")
|
||||
.allowIfSubType("java.util.")
|
||||
.allowIfSubType("java.lang.")
|
||||
.allowIfSubType("java.time.")
|
||||
.allowIfSubType("java.math.")
|
||||
.allowIfSubType("java.util.concurrent.")
|
||||
.build();
|
||||
om.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
|
||||
// LoggerFactory.useSlf4jLogging(true);
|
||||
// FuryCodec furyCodec = new FuryCodec();
|
||||
// CompositeCodec codec = new CompositeCodec(StringCodec.INSTANCE, furyCodec, furyCodec);
|
||||
|
||||
+21
-1
@@ -1,5 +1,10 @@
|
||||
package org.dromara.xg.config;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
|
||||
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -14,6 +19,7 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* 学工模块缓存配置类
|
||||
@@ -31,11 +37,25 @@ public class XgCacheConfig {
|
||||
*/
|
||||
@Bean("xgCacheManager")
|
||||
public CacheManager xgCacheManager(RedisConnectionFactory factory) {
|
||||
ObjectMapper om = new ObjectMapper();
|
||||
om.registerModule(new JavaTimeModule());
|
||||
om.setTimeZone(TimeZone.getDefault());
|
||||
// 白名单限制可反序列化类型,避免 GenericJackson2JsonRedisSerializer 默认 LaissezFaire 风险
|
||||
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder()
|
||||
.allowIfSubType("org.dromara.")
|
||||
.allowIfSubType("java.util.")
|
||||
.allowIfSubType("java.lang.")
|
||||
.allowIfSubType("java.time.")
|
||||
.allowIfSubType("java.math.")
|
||||
.build();
|
||||
om.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
|
||||
GenericJackson2JsonRedisSerializer valueSerializer = new GenericJackson2JsonRedisSerializer(om);
|
||||
|
||||
// 默认缓存配置
|
||||
RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig()
|
||||
.entryTtl(Duration.ofMinutes(30)) // 默认30分钟过期
|
||||
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
|
||||
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
|
||||
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer))
|
||||
.disableCachingNullValues(); // 不缓存null值
|
||||
|
||||
// 特定缓存配置
|
||||
|
||||
+21
-2
@@ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.*;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaMode;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
@@ -70,8 +71,15 @@ public class XgStudentStatusChangeController extends BaseController {
|
||||
|
||||
/**
|
||||
* 新增学生学籍异动
|
||||
* <p>权限与前端按钮对齐:退学/休学/复学/毕业 任一按钮权限,或历史 add 权限均可</p>
|
||||
*/
|
||||
@SaCheckPermission("studentMsg:studentStatusChange:add")
|
||||
@SaCheckPermission(value = {
|
||||
"studentMsg:status:tuixue",
|
||||
"studentMsg:status:xiuxue",
|
||||
"studentMsg:status:fuxue",
|
||||
"studentMsg:status:biye",
|
||||
"studentMsg:studentStatusChange:add"
|
||||
}, mode = SaMode.OR)
|
||||
@Log(title = "学生学籍异动", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
@@ -81,8 +89,15 @@ public class XgStudentStatusChangeController extends BaseController {
|
||||
|
||||
/**
|
||||
* 批量新增学生学籍异动(用于前端提交多个学生的异动)
|
||||
* <p>权限与前端按钮对齐:退学/休学/复学/毕业 任一按钮权限,或历史 add 权限均可</p>
|
||||
*/
|
||||
@SaCheckPermission("studentMsg:studentStatusChange:add")
|
||||
@SaCheckPermission(value = {
|
||||
"studentMsg:status:tuixue",
|
||||
"studentMsg:status:xiuxue",
|
||||
"studentMsg:status:fuxue",
|
||||
"studentMsg:status:biye",
|
||||
"studentMsg:studentStatusChange:add"
|
||||
}, mode = SaMode.OR)
|
||||
@Log(title = "学生学籍异动", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/batch")
|
||||
@@ -97,6 +112,10 @@ public class XgStudentStatusChangeController extends BaseController {
|
||||
/**
|
||||
* 复学并换班级(一次提交,事务化写入两条记录)
|
||||
*/
|
||||
@SaCheckPermission(value = {
|
||||
"studentMsg:status:fuxue",
|
||||
"studentMsg:studentStatusChange:add"
|
||||
}, mode = SaMode.OR)
|
||||
@Log(title = "学生复学并换班级", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/resume-with-class-change")
|
||||
|
||||
Reference in new issue
Block a user