From 6ed9abbe66f0e9aa0120150276a0721c6c95931a Mon Sep 17 00:00:00 2001 From: "review512jwy@163.com" <“review512jwy@163.com”> Date: Wed, 19 Nov 2025 12:21:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=89=E5=85=A8=E6=8A=A5=E5=91=8A=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../back/configurator/CrosXssFilter.java | 85 ++++++++++++++++--- .../resources/config/application.properties | 3 + dongjian-dashboard-back-dao/pom.xml | 2 +- dongjian-dashboard-back-model/pom.xml | 10 +-- dongjian-dashboard-back-service/pom.xml | 6 -- .../back/service/captcha/KaptchaConfig.java | 36 -------- dongjian-dashboard-back-util/pom.xml | 10 +-- pom.xml | 72 +++++++++++++--- 8 files changed, 143 insertions(+), 81 deletions(-) delete mode 100644 dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/captcha/KaptchaConfig.java diff --git a/dongjian-dashboard-back-controller/src/main/java/com/dongjian/dashboard/back/configurator/CrosXssFilter.java b/dongjian-dashboard-back-controller/src/main/java/com/dongjian/dashboard/back/configurator/CrosXssFilter.java index bbe3944..a236b18 100644 --- a/dongjian-dashboard-back-controller/src/main/java/com/dongjian/dashboard/back/configurator/CrosXssFilter.java +++ b/dongjian-dashboard-back-controller/src/main/java/com/dongjian/dashboard/back/configurator/CrosXssFilter.java @@ -8,7 +8,7 @@ import jakarta.servlet.FilterConfig; import jakarta.servlet.ServletException; import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletResponse; -import javax.servlet.annotation.WebFilter; +import jakarta.servlet.annotation.WebFilter; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -17,16 +17,20 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import java.util.UUID; +import org.apache.commons.lang3.StringUtils; import org.jboss.logging.MDC; @WebFilter public class CrosXssFilter implements Filter { - + private static final Logger logger = LoggerFactory.getLogger(CrosXssFilter.class); - + @Value("${crosxss.filter.disable:false}") private boolean disable; + @Value("${response.access.control.allow.origin:*}") + private String accessControlAllowOrigin; + @Override public void init(FilterConfig filterConfig) throws ServletException { } @@ -37,34 +41,89 @@ public class CrosXssFilter implements Filter { try { MDC.put("processNo", UUID.randomUUID().toString().replace("-", "")); request.setCharacterEncoding("utf-8"); -// response.setContentType("text/html;charset=utf-8"); + response.setContentType("application/json;charset=UTF-8"); if (disable) { chain.doFilter(request, response); } else { - //跨域设置 if (response instanceof HttpServletResponse) { + HttpServletResponse httpServletResponse = (HttpServletResponse) response; - //禁用浏览器缓存 - httpServletResponse.setHeader("Cache-Control", "no-store"); - //禁止被IFrame嵌套 - httpServletResponse.setHeader("X-Frame-Options", "deny"); - //安全性配置 + HttpServletRequest httpRequest = (HttpServletRequest) request; + + String referer = httpRequest.getHeader("Referer"); + if (StringUtils.isNotBlank(referer) && !"*".equals(accessControlAllowOrigin)) { + // 允许多个域名,逗号分隔 + String[] allowedOrigins = accessControlAllowOrigin.split(","); + boolean matched = false; + for (String origin : allowedOrigins) { + origin = origin.trim(); + if (StringUtils.isNotBlank(origin) && referer.startsWith(origin)) { + matched = true; + break; + } + } + // 如果一个都不匹配,则返回 403 + if (!matched) { + httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid Referer"); + return; + } + } + + + httpServletResponse.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0"); + httpServletResponse.setHeader("Pragma", "no-cache"); + httpServletResponse.setDateHeader("Expires", 0); + + httpServletResponse.setHeader("X-Frame-Options", "SAMEORIGIN"); + + String nonce = UUID.randomUUID().toString().replace("-", "").substring(0, 16); // 生成随机 nonce + httpServletResponse.setHeader("Content-Security-Policy", + "default-src 'self'; " + + "img-src 'self' data:; "+ + "font-src 'self' https://i.alicdn.com data:; "+ //阿里系的ui组件 +// "script-src 'self' 'nonce-" + nonce + "'; " + //nonce针对内联 JavaScript +// "style-src 'self' 'nonce-" + nonce + "'; " + //nonce针对内联 CSS + "script-src 'self'; " + + "style-src 'self'; " + + "object-src 'none'; " + + "base-uri 'none'; " + + "form-action 'self'; " + + "frame-ancestors 'none'" + ); httpServletResponse.setHeader("X-XSS-Protection", "1; mode=block"); httpServletResponse.setHeader("X-Content-Type-Options", "nosniff"); httpServletResponse.setHeader("Referrer-Policy", "origin"); + httpServletResponse.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload"); + + //add + httpServletResponse.addHeader("Vary", "Origin"); + httpServletResponse.addHeader("Vary", "Access-Control-Request-Method"); + httpServletResponse.addHeader("Vary", "Access-Control-Request-Headers"); + + httpServletResponse.setHeader("Access-Control-Allow-Headers", "*"); + httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, OPTIONS"); + // 设置允许的域名 + httpServletResponse.setHeader("Access-Control-Allow-Origin", accessControlAllowOrigin); + httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true"); + + + + if ("OPTIONS".equals(((HttpServletRequest) request).getMethod())) { + httpServletResponse.setStatus(HttpServletResponse.SC_OK); // 200 + return; + } } ServletRequest requestWrapper = null; if(request instanceof HttpServletRequest) { requestWrapper = new RequestWrapper((HttpServletRequest) request); } if(requestWrapper == null) { - chain.doFilter(request, response); + chain.doFilter(request, response); } else { - chain.doFilter(requestWrapper, response); + chain.doFilter(requestWrapper, response); } } } finally { - // 避免线程泄漏 MDC.clear(); } diff --git a/dongjian-dashboard-back-controller/src/main/resources/config/application.properties b/dongjian-dashboard-back-controller/src/main/resources/config/application.properties index 5c6ec8d..bd5ed46 100644 --- a/dongjian-dashboard-back-controller/src/main/resources/config/application.properties +++ b/dongjian-dashboard-back-controller/src/main/resources/config/application.properties @@ -101,11 +101,14 @@ mybatis.configuration.map-underscore-to-camel-case=true server.servlet.session.cookie.http-only=true server.servlet.session.cookie.secure=true +server.servlet.session.cookie.same-site=strict springdoc.swagger-ui.doc-expansion=none springdoc.swagger-ui.operations-sorter=alpha springdoc.swagger-ui.tags-sorter=alpha +response.access.control.allow.origin = ${accessControlAllowOrigin:*} + web.login.url=${webLoginUrl} web.admin.login.url=${webAdminLoginUrl} diff --git a/dongjian-dashboard-back-dao/pom.xml b/dongjian-dashboard-back-dao/pom.xml index 4478e96..c883c27 100644 --- a/dongjian-dashboard-back-dao/pom.xml +++ b/dongjian-dashboard-back-dao/pom.xml @@ -43,7 +43,7 @@ com.mysql mysql-connector-j - 9.3.0 + 9.5.0 diff --git a/dongjian-dashboard-back-model/pom.xml b/dongjian-dashboard-back-model/pom.xml index a7074b7..a755a1c 100644 --- a/dongjian-dashboard-back-model/pom.xml +++ b/dongjian-dashboard-back-model/pom.xml @@ -20,11 +20,11 @@ hibernate-validator 6.1.0.Final - - org.glassfish - javax.el - 3.0.1-b11 - + + jakarta.el + jakarta.el-api + 6.0.1 + org.hibernate hibernate-validator-cdi diff --git a/dongjian-dashboard-back-service/pom.xml b/dongjian-dashboard-back-service/pom.xml index 98f4bca..786d78e 100644 --- a/dongjian-dashboard-back-service/pom.xml +++ b/dongjian-dashboard-back-service/pom.xml @@ -50,11 +50,5 @@ s3 - - com.github.penggle - kaptcha - 2.3.2 - - diff --git a/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/captcha/KaptchaConfig.java b/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/captcha/KaptchaConfig.java deleted file mode 100644 index 7ea5e0d..0000000 --- a/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/captcha/KaptchaConfig.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.dongjian.dashboard.back.service.captcha; - -import java.util.Properties; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import com.google.code.kaptcha.impl.DefaultKaptcha; -import com.google.code.kaptcha.util.Config; - -@Configuration -public class KaptchaConfig { - @Bean - public DefaultKaptcha producer(){ - - DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); - Properties properties = new Properties(); - properties.setProperty("kaptcha.border", "no"); - properties.setProperty("kaptcha.border.color", "105,179,90"); - properties.setProperty("kaptcha.textproducer.font.color", "black"); - properties.setProperty("kaptcha.image.width", "110"); - properties.setProperty("kaptcha.image.height", "40"); - properties.setProperty("kaptcha.textproducer.char.string","23456789abcdefghkmnpqrstuvwxyzABCDEFGHKMNPRSTUVWXYZ"); - properties.setProperty("kaptcha.textproducer.font.size", "30"); - properties.setProperty("kaptcha.textproducer.char.space","3"); - properties.setProperty("kaptcha.session.key", "code"); - properties.setProperty("kaptcha.textproducer.char.length", "4"); - properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑"); -// properties.setProperty("kaptcha.obscurificator.impl","com.xxx");可以重写实现类 - properties.setProperty("kaptcha.noise.impl","com.google.code.kaptcha.impl.NoNoise"); - Config config = new Config(properties); - defaultKaptcha.setConfig(config); - - return defaultKaptcha; - } -} \ No newline at end of file diff --git a/dongjian-dashboard-back-util/pom.xml b/dongjian-dashboard-back-util/pom.xml index 011be30..af9708d 100644 --- a/dongjian-dashboard-back-util/pom.xml +++ b/dongjian-dashboard-back-util/pom.xml @@ -31,12 +31,8 @@ org.springframework.boot spring-boot-starter-data-redis - + - org.apache.commons - commons-lang3 - - org.apache.commons commons-pool2 @@ -60,7 +56,7 @@ commons-io commons-io - 2.11.0 + 2.18.0 @@ -78,7 +74,7 @@ org.springframework.security spring-security-oauth2-authorization-server - 1.5.1 + 1.5.3 diff --git a/pom.xml b/pom.xml index 330d982..00426e6 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.springframework.boot spring-boot-starter-parent - 3.2.12 + 3.5.7 @@ -55,7 +55,7 @@ org.apache.tomcat.embed tomcat-embed-core - 10.1.42 + 10.1.49 org.springframework.boot @@ -80,7 +80,7 @@ org.springdoc springdoc-openapi-starter-webmvc-ui - 2.5.0 + 2.8.14 @@ -91,17 +91,17 @@ com.fasterxml.jackson.core jackson-core - 2.19.0 + 2.19.4 com.fasterxml.jackson.core jackson-databind - 2.19.0 + 2.19.4 com.fasterxml.jackson.core jackson-annotations - 2.19.0 + 2.19.4 @@ -113,7 +113,7 @@ com.mysql mysql-connector-j - 9.3.0 + 9.5.0 @@ -139,20 +139,27 @@ ch.qos.logback logback-classic - 1.5.18 + 1.5.21 compile ch.qos.logback logback-core - 1.5.18 + 1.5.21 compile + + + + org.apache.commons + commons-lang3 + 3.20.0 + org.apache.commons commons-compress - 1.27.1 + 1.28.0 @@ -177,19 +184,19 @@ io.lettuce lettuce-core - 6.7.1.RELEASE + 6.8.1.RELEASE org.apache.logging.log4j log4j-core - 2.25.1 + 2.25.2 org.apache.logging.log4j log4j-api - 2.25.1 + 2.25.2 @@ -198,6 +205,12 @@ easyexcel 4.0.3 + + + com.nimbusds + nimbus-jose-jwt + 10.6 + @@ -210,6 +223,39 @@ pom import + + + io.netty + netty-bom + 4.1.128.Final + pom + import + + + + org.apache.poi + poi + 5.5.0 + + + + org.apache.poi + poi-ooxml + 5.5.0 + + + + org.apache.poi + poi-ooxml-lite + 5.5.0 + + + + + org.apache.xmlbeans + xmlbeans + 5.2.0 +