| | |
| | | import reactor.core.publisher.Mono; |
| | | |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.Arrays; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | |
| | | public class SensitiveDataMaskingGlobalFilter implements GlobalFilter, Ordered { |
| | | private static final Pattern FIELD = Pattern.compile("(?i)(\\\"(?:[a-z]*phone|[a-z]*mobile|telephone|tel)\\\"\\s*:\\s*\\\")([^\\\"]*)(\\\")"); |
| | | private static final Pattern IDCARD = Pattern.compile("(?i)(\\\"(?:[a-z]*idcard|[a-z]*identitycard|identitynumber|idnumber)\\\"\\s*:\\s*\\\")([^\\\"]*)(\\\")"); |
| | | /** |
| | | * APP has to receive these values so it can apply its own display masking. |
| | | * Keep this list exact: all other routes continue to be protected at the |
| | | * gateway boundary. |
| | | */ |
| | | private static final Set<String> APP_UNMASKED_PATHS = new HashSet<String>(Arrays.asList( |
| | | "/other/api/site/queryMySiteById", |
| | | "/account/base/exploreWP/storeDetail", |
| | | "/other/base/store/queryStoreFreeBenefit", |
| | | "/other/base/site/querySiteInfo", |
| | | "/activity/huimin/getStudentListByCarId", |
| | | "/account/base/exploreWP/customerList" |
| | | )); |
| | | |
| | | @Override public int getOrder() { return -2; } |
| | | |
| | | @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { |
| | | // This route itself enforces the admin check and writes an audit record. |
| | | if (exchange.getRequest().getURI().getPath().startsWith("/system/sensitive/")) return chain.filter(exchange); |
| | | String path = exchange.getRequest().getURI().getPath(); |
| | | // /system/sensitive enforces its own admin check and audit. The APP |
| | | // paths below deliberately return their original fields for client-side |
| | | // display masking; every other response remains gateway-masked. |
| | | if (path.startsWith("/system/sensitive/") || APP_UNMASKED_PATHS.contains(path)) return chain.filter(exchange); |
| | | ServerHttpResponseDecorator decorated = new ServerHttpResponseDecorator(exchange.getResponse()) { |
| | | @Override public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) { |
| | | MediaType type = getHeaders().getContentType(); |