刘帅
2026-09-29 b55cd9aad0835a96a790e61f9f89edc2fae1be9f
cloud-server-management/src/main/java/com/dsh/privacy/SensitiveDataMaskingAdvice.java
@@ -15,14 +15,14 @@
import java.util.Iterator;
import java.util.Map;
/** Ensures every normal management JSON response uses the same privacy rules. */
/** 确保所有常规管理端 JSON 响应均遵循统一的隐私保护规则。 */
@ControllerAdvice
public class SensitiveDataMaskingAdvice implements ResponseBodyAdvice<Object> {
    private final HttpServletRequest request;
    public SensitiveDataMaskingAdvice(HttpServletRequest request) { this.request = request; }
    @Override public boolean supports(MethodParameter type, Class<? extends HttpMessageConverter<?>> converter) {
        // Only the explicit, admin-only and audited endpoint returns the source value.
        // 仅明确限定、仅管理员可访问且已审计的接口返回原始数据。
        return !request.getRequestURI().startsWith("/system/sensitive/");
    }
    @Override public Object beforeBodyWrite(Object body, MethodParameter type, MediaType mediaType,
@@ -32,13 +32,12 @@
    }
    private void mask(Object value, IdentityHashMap<Object, Boolean> seen) {
        if (value == null || value instanceof String || value.getClass().isEnum() || seen.put(value, Boolean.TRUE) != null) return;
        // Reactive streams and their internal queues are runtime infrastructure, not
        // response DTOs. In particular, Reactor's MpscLinkedQueue implements
        // Iterable but deliberately throws UnsupportedOperationException from
        // iterator(). Do not introspect it (or any other reactive infrastructure).
        // 响应式流及其内部队列属于运行时基础设施,并非响应 DTO。特别是 Reactor 的
        // MpscLinkedQueue 虽实现了 Iterable,却会在 iterator() 中主动抛出
        // UnsupportedOperationException;不得反射遍历它或其他响应式基础设施。
        if (isReactiveInfrastructure(value.getClass())) return;
        // UnixPath implements Iterable.  Its iterator creates a new Path for every
        // segment, so identity-based cycle detection cannot stop the recursion.
        // UnixPath 实现了 Iterable,其迭代器会为每个路径段创建新的 Path 对象,
        // 因此基于对象标识的循环检测无法终止递归。
        if (value instanceof Path) return;
        if (value instanceof Map) {
            for (Object item : ((Map<?, ?>) value).entrySet()) {
@@ -62,16 +61,15 @@
    }
    /**
     * Some third-party containers expose Iterable only for API compatibility and
     * intentionally do not support iteration. A response privacy filter must never
     * turn such an implementation detail into a 500 response.
     * 部分第三方容器仅为 API 兼容而实现 Iterable,并不支持实际迭代。
     * 响应隐私过滤器不得因这类实现细节导致接口返回 500 错误。
     */
    private void maskIterable(Iterable<?> values, IdentityHashMap<Object, Boolean> seen) {
        try {
            Iterator<?> iterator = values.iterator();
            while (iterator.hasNext()) mask(iterator.next(), seen);
        } catch (UnsupportedOperationException ignored) {
            // There is no safely accessible element to mask.
            // 没有可安全访问并进行脱敏的元素。
        }
    }