diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/config/OrionDesensitizeAutoConfiguration.java b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/config/OrionDesensitizeAutoConfiguration.java index 6e8f0861..b15ceae8 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/config/OrionDesensitizeAutoConfiguration.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/config/OrionDesensitizeAutoConfiguration.java @@ -1,14 +1,13 @@ package com.orion.ops.framework.desensitize.config; -import com.alibaba.fastjson.serializer.SerializeFilter; -import com.alibaba.fastjson.support.config.FastJsonConfig; -import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; -import com.orion.lang.utils.Arrays1; -import com.orion.ops.framework.desensitize.core.filter.DesensitizeValueSerializeFilter; +import com.orion.ops.framework.common.constant.AutoConfigureOrderConst; +import com.orion.ops.framework.desensitize.core.filter.DesensitizeValueFilter; +import com.orion.ops.framework.desensitize.core.serializer.DesensitizeJsonSerializer; import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.context.annotation.Bean; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; /** * 数据脱敏置类 @@ -20,32 +19,25 @@ import org.springframework.context.annotation.Bean; * @since 2023/6/29 16:55 */ @AutoConfiguration -@AutoConfigureAfter(name = "com.orion.ops.framework.web.config.OrionWebAutoConfiguration") +@AutoConfigureOrder(AutoConfigureOrderConst.FRAMEWORK_DESENSITIZE) public class OrionDesensitizeAutoConfiguration { /** - * @return 返回 序列化脱敏过滤器 + * @return fastjson 序列化脱敏过滤器 */ @Bean - @ConditionalOnBean(FastJsonHttpMessageConverter.class) - public DesensitizeValueSerializeFilter desensitizeValueSerializeFilter(FastJsonHttpMessageConverter converter) { - DesensitizeValueSerializeFilter desensitizeFilter = new DesensitizeValueSerializeFilter(); - // 获取 json 配置 - FastJsonConfig config = converter.getFastJsonConfig(); - SerializeFilter[] filters = config.getSerializeFilters(); - int filterLength = Arrays1.length(filters); - if (filterLength == 0) { - // 未设置配置 - filters = new SerializeFilter[]{desensitizeFilter}; - } else { - SerializeFilter[] newFilters = new SerializeFilter[filterLength + 1]; - System.arraycopy(filters, 0, newFilters, 0, filterLength); - newFilters[filterLength] = desensitizeFilter; - filters = newFilters; - } - // 更新到配置 - config.setSerializeFilters(filters); - return desensitizeFilter; + public DesensitizeValueFilter desensitizeValueFilter() { + return new DesensitizeValueFilter(); + } + + /** + * @return jackson 序列化脱敏过滤器 + */ + @Bean + @ConditionalOnBean(MappingJackson2HttpMessageConverter.class) + public DesensitizeJsonSerializer desensitizeJsonSerializer(MappingJackson2HttpMessageConverter converter) { + DesensitizeJsonSerializer serializer = new DesensitizeJsonSerializer(); + return serializer; } } diff --git a/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/Desensitize.java b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/annotation/Desensitize.java similarity index 61% rename from orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/Desensitize.java rename to orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/annotation/Desensitize.java index c112f322..56ee6bba 100644 --- a/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/Desensitize.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/annotation/Desensitize.java @@ -1,4 +1,8 @@ -package com.orion.ops.framework.common.annotation; +package com.orion.ops.framework.desensitize.core.annotation; + +import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.orion.ops.framework.desensitize.core.serializer.DesensitizeJsonSerializer; import java.lang.annotation.*; @@ -14,6 +18,8 @@ import java.lang.annotation.*; @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented +@JacksonAnnotationsInside +@JsonSerialize(using = DesensitizeJsonSerializer.class) public @interface Desensitize { /** diff --git a/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/DesensitizeObject.java b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/annotation/DesensitizeObject.java similarity index 84% rename from orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/DesensitizeObject.java rename to orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/annotation/DesensitizeObject.java index 86d84269..730f92c1 100644 --- a/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/DesensitizeObject.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/annotation/DesensitizeObject.java @@ -1,4 +1,4 @@ -package com.orion.ops.framework.common.annotation; +package com.orion.ops.framework.desensitize.core.annotation; import java.lang.annotation.*; diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/filter/DesensitizeValueSerializeFilter.java b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/filter/DesensitizeValueFilter.java similarity index 89% rename from orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/filter/DesensitizeValueSerializeFilter.java rename to orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/filter/DesensitizeValueFilter.java index 819cd90a..9d334a45 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/filter/DesensitizeValueSerializeFilter.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/filter/DesensitizeValueFilter.java @@ -8,8 +8,8 @@ import com.orion.lang.utils.Strings; import com.orion.lang.utils.collect.Maps; import com.orion.lang.utils.reflect.Annotations; import com.orion.lang.utils.reflect.Fields; -import com.orion.ops.framework.common.annotation.Desensitize; -import com.orion.ops.framework.common.annotation.DesensitizeObject; +import com.orion.ops.framework.desensitize.core.annotation.Desensitize; +import com.orion.ops.framework.desensitize.core.annotation.DesensitizeObject; import java.lang.reflect.Field; import java.util.HashMap; @@ -17,13 +17,15 @@ import java.util.List; import java.util.Map; /** - * 脱敏序列化器 + * fastjson 脱敏序列化器 + *

+ * 用于全局日志打印 * * @author Jiahang Li * @version 1.0.0 * @since 2023/6/30 12:19 */ -public class DesensitizeValueSerializeFilter implements ValueFilter { +public class DesensitizeValueFilter implements ValueFilter { private static final Map> DESENSITIZE_FIELDS = new HashMap<>(); @@ -32,7 +34,7 @@ public class DesensitizeValueSerializeFilter implements ValueFilter { if (object == null || value == null) { return value; } - Desensitize config = doDesensitizeField(object, name); + Desensitize config = this.doDesensitizeField(object, name); // 无需脱敏 if (config == null) { return value; diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/serializer/DesensitizeJsonSerializer.java b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/serializer/DesensitizeJsonSerializer.java new file mode 100644 index 00000000..2cef2819 --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/serializer/DesensitizeJsonSerializer.java @@ -0,0 +1,52 @@ +package com.orion.ops.framework.desensitize.core.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.BeanProperty; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.ContextualSerializer; +import com.orion.lang.utils.Desensitizes; +import com.orion.lang.utils.Objects1; +import com.orion.ops.framework.desensitize.core.annotation.Desensitize; + +import java.io.IOException; +import java.util.Objects; + +/** + * jackson 脱敏序列化器 + *

+ * 用于 http 响应 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/7/11 17:10 + */ +public class DesensitizeJsonSerializer extends JsonSerializer implements ContextualSerializer { + + private Desensitize desensitize; + + @Override + public JsonSerializer createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { + Desensitize desensitize = property.getAnnotation(Desensitize.class); + if (Objects.nonNull(desensitize)) { + this.desensitize = desensitize; + return this; + } + return prov.findValueSerializer(property.getType(), property); + + } + + @Override + public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + // 为空判断 + if (value == null) { + gen.writeNull(); + return; + } + // 脱敏 + String mix = Desensitizes.mix(Objects1.toString(value), desensitize.keepStart(), desensitize.keepEnd(), desensitize.replacer()); + gen.writeString(mix); + } + +} \ No newline at end of file diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-log/src/main/java/com/orion/ops/framework/log/core/interceptor/AbstractLogPrinterInterceptor.java b/orion-ops-framework/orion-ops-spring-boot-starter-log/src/main/java/com/orion/ops/framework/log/core/interceptor/AbstractLogPrinterInterceptor.java index d6cf36b9..273ab08b 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-log/src/main/java/com/orion/ops/framework/log/core/interceptor/AbstractLogPrinterInterceptor.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-log/src/main/java/com/orion/ops/framework/log/core/interceptor/AbstractLogPrinterInterceptor.java @@ -62,8 +62,8 @@ public abstract class AbstractLogPrinterInterceptor implements LogPrinterInterce @SuppressWarnings("ALL") @Autowired(required = false) - @Qualifier("desensitizeValueSerializeFilter") - private ValueFilter desensitizeValueSerializeFilter; + @Qualifier("desensitizeValueFilter") + private ValueFilter desensitizeValueFilter; public AbstractLogPrinterInterceptor(LogPrinterConfig config) { this.config = config; @@ -89,8 +89,8 @@ public abstract class AbstractLogPrinterInterceptor implements LogPrinterInterce fieldFilterList.add(ignoreFilter); fieldFilterList.add(desensitizeFilter); // 注解脱敏 未引入 - if (desensitizeValueSerializeFilter != null) { - fieldFilterList.add(desensitizeValueSerializeFilter); + if (desensitizeValueFilter != null) { + fieldFilterList.add(desensitizeValueFilter); } this.fieldFilters = fieldFilterList.toArray(new SerializeFilter[0]); } diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/config/OrionWebAutoConfiguration.java b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/config/OrionWebAutoConfiguration.java index c2e91ce1..65765d37 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/config/OrionWebAutoConfiguration.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/config/OrionWebAutoConfiguration.java @@ -1,30 +1,27 @@ package com.orion.ops.framework.web.config; -import com.alibaba.fastjson.serializer.SerializerFeature; -import com.alibaba.fastjson.support.config.FastJsonConfig; -import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.orion.lang.utils.collect.Lists; +import com.orion.ops.framework.common.constant.AutoConfigureOrderConst; import com.orion.ops.framework.common.constant.FilterOrderConst; import com.orion.ops.framework.common.filter.FilterCreator; -import com.orion.ops.framework.web.core.convert.CustomerFastJsonHttpMessageConverter; -import com.orion.ops.framework.web.core.convert.SerializeConfig; import com.orion.ops.framework.web.core.filter.TraceIdFilter; import com.orion.ops.framework.web.core.handler.GlobalExceptionHandler; import com.orion.ops.framework.web.core.handler.WrapperResultHandler; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; -import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.http.MediaType; import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.ResourceRegionHttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.util.AntPathMatcher; import org.springframework.web.bind.annotation.RestController; @@ -48,7 +45,7 @@ import java.util.List; * @since 2023/6/16 16:26 */ @AutoConfiguration -@EnableConfigurationProperties(SerializeConfig.class) +@AutoConfigureOrder(AutoConfigureOrderConst.FRAMEWORK_WEB) public class OrionWebAutoConfiguration implements WebMvcConfigurer { @Value("${orion.api.prefix}") @@ -78,39 +75,6 @@ public class OrionWebAutoConfiguration implements WebMvcConfigurer { return new WrapperResultHandler(); } - /** - * @param serializeConfig 序列化配置 - * @return http message fast json 转换器 - */ - @Bean - public FastJsonHttpMessageConverter fastJsonHttpMessageConverter(SerializeConfig serializeConfig) { - // json 转换器 - CustomerFastJsonHttpMessageConverter converter = new CustomerFastJsonHttpMessageConverter(serializeConfig); - // 配置 - FastJsonConfig config = new FastJsonConfig(); - // 支持的类型 - List mediaTypes = Lists.of( - MediaType.APPLICATION_JSON, - MediaType.APPLICATION_FORM_URLENCODED, - MediaType.APPLICATION_XHTML_XML, - MediaType.TEXT_PLAIN, - MediaType.TEXT_HTML, - MediaType.TEXT_XML - ); - converter.setSupportedMediaTypes(mediaTypes); - // 序列化配置 - config.setSerializerFeatures( - SerializerFeature.DisableCircularReferenceDetect, - SerializerFeature.WriteMapNullValue, - SerializerFeature.WriteNullListAsEmpty, - SerializerFeature.IgnoreNonFieldGetter - ); - config.setCharset(StandardCharsets.UTF_8); - converter.setFastJsonConfig(config); - converter.setDefaultCharset(StandardCharsets.UTF_8); - return converter; - } - /** * @return http message jackson 转换器 */ @@ -125,9 +89,11 @@ public class OrionWebAutoConfiguration implements WebMvcConfigurer { MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.TEXT_XML, - new MediaType("application", "vnd.spring-boot.actuator.v2+json") + MediaType.ALL ); converter.setSupportedMediaTypes(mediaTypes); + converter.setDefaultCharset(StandardCharsets.UTF_8); + // 默认 objectMapper ObjectMapper objectMapper = converter.getObjectMapper(); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 序列化配置 @@ -142,18 +108,14 @@ public class OrionWebAutoConfiguration implements WebMvcConfigurer { * @return http message 转换器列表 */ @Bean - public HttpMessageConverters httpMessageConverters(FastJsonHttpMessageConverter fastJsonConverter, - MappingJackson2HttpMessageConverter jacksonConvert) { - List> defaultConverters = new HttpMessageConverters().getConverters(); + public HttpMessageConverters httpMessageConverters(MappingJackson2HttpMessageConverter jacksonConvert) { List> converters = new ArrayList<>(); - // 将 byte converter 添加至首位 - fix swagger api 返回base64报错 + // 添加 byte converter - swagger api converters.add(new ByteArrayHttpMessageConverter()); - // 添加自定义 converter - using WrapperResultHandler/脱敏 - converters.add(fastJsonConverter); - // 添加自定义 converter - jackson + // 添加 resource region - admin api log + converters.add(new ResourceRegionHttpMessageConverter()); + // 添加 json converter - jackson converters.add(jacksonConvert); - // 添加默认处理器 - converters.addAll(defaultConverters); return new HttpMessageConverters(false, converters); } diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/convert/CustomerFastJsonHttpMessageConverter.java b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/convert/CustomerFastJsonHttpMessageConverter.java deleted file mode 100644 index 856d296d..00000000 --- a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/convert/CustomerFastJsonHttpMessageConverter.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.orion.ops.framework.web.core.convert; - -import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; -import org.springframework.http.MediaType; - -import java.lang.reflect.Type; -import java.util.List; - -/** - * 自定义 fastjson 转换器 - * - * @author Jiahang Li - * @version 1.0.0 - * @since 2023/7/11 11:46 - */ -public class CustomerFastJsonHttpMessageConverter extends FastJsonHttpMessageConverter { - - private final SerializeConfig serializeConfig; - - public CustomerFastJsonHttpMessageConverter(SerializeConfig serializeConfig) { - this.serializeConfig = serializeConfig; - } - - @Override - public boolean canRead(Type type, Class contextClass, MediaType mediaType) { - List unsupportedClasses = serializeConfig.getUnsupportedClasses(); - if (unsupportedClasses != null) { - if (unsupportedClasses.contains(contextClass.getName())) { - return false; - } - } - return super.canRead(type, contextClass, mediaType); - } - - @Override - public boolean canWrite(Type type, Class clazz, MediaType mediaType) { - return super.canWrite(type, clazz, mediaType); - } - -} diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/convert/SerializeConfig.java b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/convert/SerializeConfig.java deleted file mode 100644 index d2c4d7c3..00000000 --- a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/convert/SerializeConfig.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.orion.ops.framework.web.core.convert; - -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; - -import java.util.ArrayList; -import java.util.List; - -/** - * 序列化配置 - * - * @author Jiahang Li - * @version 1.0.0 - * @since 2023/7/11 14:57 - */ -@Data -@ConfigurationProperties("orion.serializer") -public class SerializeConfig { - - /** - * 不支持的序列化类型 - */ - private List unsupportedClasses; - - public SerializeConfig() { - this.unsupportedClasses = new ArrayList<>(); - } - -} diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/resources/META-INF/spring-configuration-metadata.json b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/resources/META-INF/spring-configuration-metadata.json index e6639d6f..b506adc4 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/resources/META-INF/spring-configuration-metadata.json +++ b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/resources/META-INF/spring-configuration-metadata.json @@ -14,11 +14,6 @@ "name": "orion.api.cors", "type": "java.lang.Boolean", "description": "是否开启 cors 过滤器." - }, - { - "name": "orion.serializer.unsupported-classes", - "type": "java.util.List", - "description": "不支持的序列化类型." } ] } \ No newline at end of file diff --git a/orion-ops-launch/src/main/resources/application.yaml b/orion-ops-launch/src/main/resources/application.yaml index 3dd6bbf5..b8aae4b3 100644 --- a/orion-ops-launch/src/main/resources/application.yaml +++ b/orion-ops-launch/src/main/resources/application.yaml @@ -133,11 +133,6 @@ orion: prefix: /orion-api # 是否开启跨域 cors: true - serializer: - # 不支持的序列化类型 - unsupported-classes: - - de.codecentric.boot.admin.server.web.InstancesController - - org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler swagger: # swagger 配置 title: orion-ops-pro 运维平台