This commit is contained in:
parent
a48e74e815
commit
341990088e
|
|
@ -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<String> PROTECTED_PATH_PREFIXES = Arrays.asList(
|
||||
"/login", "/admin", "/PMA", "/html", "/sitemap.xml",
|
||||
"/db", "/dbadmin", "/myadmin", "/mysql", "/mysqladmin",
|
||||
"/phpMyAdmin", "/phpMyAdmin2"
|
||||
);
|
||||
|
||||
|
||||
@Override
|
||||
public Mono<Void> 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -12,9 +12,22 @@
|
|||
</title>
|
||||
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
|
||||
|
||||
<script async src="https://api.map.baidu.com/api?v=2.0&ak=cClgLBaLgGUdQDilX9dGvieL"></script>
|
||||
<script src="https://api.map.baidu.com/api?type=webgl&v=2.0&ak=cClgLBaLgGUdQDilX9dGvieL"></script>
|
||||
<script type="text/javascript" src="//api.map.baidu.com/library/TrackAnimation/src/TrackAnimation_min.js"></script>
|
||||
<!-- 百度一旦更新,散列会变,上线前重新跑一遍-->
|
||||
<script async src="https://api.map.baidu.com/api?v=2.0&ak=cClgLBaLgGUdQDilX9dGvieL"
|
||||
integrity="sha384-8be4499e12b47c9a2f6b90a4e9025fcfd289ddca34c4756ec1e03dd78026f752d0a53ea36791ac6c8391300f04491304"
|
||||
crossorigin="anonymous">
|
||||
</script>
|
||||
|
||||
<script src="https://api.map.baidu.com/api?type=webgl&v=2.0&ak=cClgLBaLgGUdQDilX9dGvieL"
|
||||
integrity="sha384-c0942dfc4beaea6aa68a3634d6e4b38aed2ccee2a528f05c15825024bf4da336cda71d23845c116443f2af322851706f"
|
||||
crossorigin="anonymous">
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="//api.map.baidu.com/library/TrackAnimation/src/TrackAnimation_min.js"
|
||||
integrity="sha384-399331ab3feebedced9c52983a82a0bf86f61ca52e078de821413eca9b5a69f4b796e7a1c7b6ea67f2f415d5c27bcb69"
|
||||
crossorigin="anonymous">
|
||||
</script>
|
||||
|
||||
<style>
|
||||
html,
|
||||
body,
|
||||
|
|
|
|||
Loading…
Reference in New Issue