From 341990088e0632179301eb7103630b4b9fc6789b Mon Sep 17 00:00:00 2001 From: itcast Date: Thu, 23 Oct 2025 18:25:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=BC=8F=E6=B4=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gateway/filter/SecurityHeaderFilter.java | 120 ++++++++++++++++++ sgzb-ui/public/index.html | 21 ++- 2 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 sgzb-gateway/src/main/java/com/bonus/sgzb/gateway/filter/SecurityHeaderFilter.java diff --git a/sgzb-gateway/src/main/java/com/bonus/sgzb/gateway/filter/SecurityHeaderFilter.java b/sgzb-gateway/src/main/java/com/bonus/sgzb/gateway/filter/SecurityHeaderFilter.java new file mode 100644 index 00000000..7cbd07e9 --- /dev/null +++ b/sgzb-gateway/src/main/java/com/bonus/sgzb/gateway/filter/SecurityHeaderFilter.java @@ -0,0 +1,120 @@ +package com.bonus.sgzb.gateway.filter; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.core.Ordered; +import org.springframework.http.HttpHeaders; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +import java.util.Arrays; +import java.util.List; + +/** + * @author 30791 + * @version 1.0 + * Create by 2025/10/23 13:26 + */ + +@Slf4j +@Component +public class SecurityHeaderFilter implements GlobalFilter, Ordered { + + // 定义需要添加安全头的页面路径 + private static final List PROTECTED_PATH_PREFIXES = Arrays.asList( + "/login", "/admin", "/PMA", "/html", "/sitemap.xml", + "/db", "/dbadmin", "/myadmin", "/mysql", "/mysqladmin", + "/phpMyAdmin", "/phpMyAdmin2" + ); + + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + + ServerHttpRequest request = exchange.getRequest(); + ServerHttpResponse response = exchange.getResponse(); + String path = request.getPath().value(); + String method = request.getMethod().name(); + + log.debug("SecurityHeaderFilter 处理请求: {},{}", method, path); + + //获取响应头 + HttpHeaders headers = response.getHeaders(); + + //检查是否为受保护路径 + boolean protectedPath = isProtectedPath(path); + + //设置 Referrer-Policy(所有请求都应用) + headers.set("Referrer-Policy", "strict-origin-when-cross-origin"); + + + if (protectedPath) { + //点击添加劫持防护头 + headers.add("X-Frame-Options", "DENY"); + + // 改成完整的 CSP,仍保留“禁止被嵌套” + headers.add("Content-Security-Policy", + "default-src 'self'; " + // 默认仅本域 + "script-src 'self' https://code.jquery.com; " + // 允许 jQuery CDN + "style-src 'self' 'unsafe-inline'; " + // 本域 CSS + 内联 + "img-src 'self' data:; " + // 本域图片、data URI + "frame-ancestors 'none'"); // 继续禁止被 iframe + + + log.info("未受保护路径 {} 添加严格安全头部", path); + + // 调试日志 + if (log.isDebugEnabled()) { + log.debug("设置的严格安全头部:"); + log.debug(" X-Frame-Options: DENY"); + log.debug(" Content-Security-Policy: frame-ancestors 'none'"); + } + } else { + //即使未受保护路径,也添加基本安全头 + headers.add("X-Frame-Options", "SAMEORIGIN"); + + // 改成完整的 CSP,仍保留“禁止被嵌套” + headers.add("Content-Security-Policy", + "default-src 'self'; " + // 默认仅本域 + "script-src 'self' https://code.jquery.com; " + // 允许 jQuery CDN + "style-src 'self' 'unsafe-inline'; " + // 本域 CSS + 内联 + "img-src 'self' data:; " + // 本域图片、data URI + "frame-ancestors 'none'"); // 继续禁止被 iframe + + log.debug("为普通路径 {} 添加基本安全头部", path); + } + + return chain.filter(exchange); + } + + @Override + public int getOrder() { + // 设置过滤器执行顺序,数字越小优先级越高 + // 设置为高位值,确保在路由之后执行,能够修改响应头 + return LOWEST_PRECEDENCE; + } + + /** + * 检查请求路径是否为受保护路径 + * + * @param requestPath + * @return + */ + + private boolean isProtectedPath(String requestPath) { + + for (String prefix : PROTECTED_PATH_PREFIXES) { + if (requestPath.startsWith(prefix)) { + log.debug("路径 {} 匹配受保护前缀: {}", requestPath, prefix); + return true; + } + } + + return false; + } +} diff --git a/sgzb-ui/public/index.html b/sgzb-ui/public/index.html index e0dcd345..fa84b9c2 100644 --- a/sgzb-ui/public/index.html +++ b/sgzb-ui/public/index.html @@ -12,9 +12,22 @@ - - - + + + + + + +