| | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Response boundary protection for personal phone and identity-card data. |
| | | * It is deliberately based on field names so it also covers ad-hoc Maps |
| | | * produced by reporting APIs. |
| | | * 手机号和身份证号等个人敏感数据的响应边界保护。 |
| | | * 基于字段名进行识别,因此也可覆盖报表接口临时生成的 Map 数据。 |
| | | */ |
| | | @ControllerAdvice |
| | | public class SensitiveDataMaskingAdvice implements ResponseBodyAdvice<Object> { |
| | | private static final String INTERNAL_SENSITIVE_ACCESS = "X-Internal-Sensitive-Access"; |
| | | /** APP endpoints whose clients receive original values and mask only when displaying them. */ |
| | | /** 客户端接收原始数据、仅在展示时脱敏的 APP 接口。 */ |
| | | private static final Set<String> APP_UNMASKED_PATHS = new HashSet<String>(Arrays.asList( |
| | | "/base/exploreWP/storeDetail", |
| | | "/base/exploreWP/customerList" |
| | |
| | | @Override |
| | | public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { |
| | | String path = request.getRequestURI(); |
| | | // Internal management calls require their sensitive-access header. The |
| | | // two explicitly listed APP endpoints return original values for |
| | | // client-side display masking; all other account responses are masked. |
| | | // 内部管理调用必须携带敏感数据访问请求头。明确列出的两个 APP 接口返回原始数据, |
| | | // 由客户端在展示时脱敏;其他账户服务响应均进行脱敏。 |
| | | return !(APP_UNMASKED_PATHS.contains(path) |
| | | || (path.startsWith("/internal/sensitive/") |
| | | && "true".equalsIgnoreCase(request.getHeader(INTERNAL_SENSITIVE_ACCESS)))); |