From e5da5096c3f462a50e7bb241fbb9e136638fd500 Mon Sep 17 00:00:00 2001 From: van Date: Sat, 5 Sep 2026 17:33:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0springboot2=20=E4=BE=9D?= =?UTF-8?q?=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 10 +-- .../src/main/resources/application-dev.yml | 7 ++ .../src/main/resources/application-prod.yml | 7 ++ .../com/ruoyi/common/constant/Constants.java | 2 +- .../common/core/domain/entity/SysUser.java | 2 + .../ruoyi/common/filter/RefererFilter.java | 77 +++++++++++++++++++ .../ruoyi/framework/config/FilterConfig.java | 22 ++++++ 7 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/filter/RefererFilter.java diff --git a/pom.xml b/pom.xml index a798321..fd270af 100644 --- a/pom.xml +++ b/pom.xml @@ -19,21 +19,21 @@ 1.8 3.1.1 2.5.15 - 1.2.23 + 1.2.28 1.21 3.0.0 2.3.3 1.4.7 - 2.0.57 + 2.0.64 6.8.2 - 2.19.0 + 2.22.0 4.1.2 2.3 0.9.1 - 9.0.106 + 9.0.112 1.2.13 - 5.7.12 + 5.7.14 5.3.39 2.2.3 diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index bf13a50..c26daf5 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -179,6 +179,13 @@ swagger: # 请求前缀 pathMapping: /dev-api +# 防盗链配置(开启前请确认允许的前端域名,避免头像/上传资源被拦截) +referer: + # 防盗链开关 + enabled: false + # 允许的域名列表 + allowed-domains: localhost,127.0.0.1 + # 防止XSS攻击 xss: # 过滤开关 diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml index f3f6038..5687a5e 100644 --- a/ruoyi-admin/src/main/resources/application-prod.yml +++ b/ruoyi-admin/src/main/resources/application-prod.yml @@ -179,6 +179,13 @@ swagger: # 请求前缀 pathMapping: /dev-api +# 防盗链配置(开启前请确认允许的前端域名,避免头像/上传资源被拦截) +referer: + # 防盗链开关 + enabled: false + # 允许的域名列表 + allowed-domains: localhost,127.0.0.1,jarvis.van333.cn + # 防止XSS攻击 xss: # 过滤开关 diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java index 0c384c6..b1d4775 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -158,7 +158,7 @@ public class Constants /** * 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全) */ - public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.ruoyi" }; + public static final String[] JSON_WHITELIST_STR = { "com.ruoyi" }; /** * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加) diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java index d133ee8..0109891 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java @@ -5,6 +5,7 @@ import java.util.List; import javax.validation.constraints.*; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; +import com.fasterxml.jackson.annotation.JsonProperty; import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.annotation.Excel.ColumnType; import com.ruoyi.common.annotation.Excel.Type; @@ -200,6 +201,7 @@ public class SysUser extends BaseEntity this.avatar = avatar; } + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) public String getPassword() { return password; diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/filter/RefererFilter.java b/ruoyi-common/src/main/java/com/ruoyi/common/filter/RefererFilter.java new file mode 100644 index 0000000..1de5027 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/filter/RefererFilter.java @@ -0,0 +1,77 @@ +package com.ruoyi.common.filter; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 防盗链过滤器 + * + * @author ruoyi + */ +public class RefererFilter implements Filter +{ + /** + * 允许的域名列表 + */ + public List allowedDomains; + + @Override + public void init(FilterConfig filterConfig) throws ServletException + { + String domains = filterConfig.getInitParameter("allowedDomains"); + this.allowedDomains = Arrays.asList(domains.split(",")); + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException + { + HttpServletRequest req = (HttpServletRequest) request; + HttpServletResponse resp = (HttpServletResponse) response; + + String referer = req.getHeader("Referer"); + + // 如果Referer为空,拒绝访问 + if (referer == null || referer.isEmpty()) + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Access denied: Referer header is required"); + return; + } + + // 检查Referer是否在允许的域名列表中 + boolean allowed = false; + for (String domain : allowedDomains) + { + if (referer.contains(domain)) + { + allowed = true; + break; + } + } + + // 根据检查结果决定是否放行 + if (allowed) + { + chain.doFilter(request, response); + } + else + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Access denied: Referer '" + referer + "' is not allowed"); + } + } + + @Override + public void destroy() + { + + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java index bb14c04..c00aa15 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java @@ -8,6 +8,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.filter.RefererFilter; import com.ruoyi.common.filter.RepeatableFilter; import com.ruoyi.common.filter.XssFilter; import com.ruoyi.common.utils.StringUtils; @@ -26,6 +28,9 @@ public class FilterConfig @Value("${xss.urlPatterns}") private String urlPatterns; + @Value("${referer.allowed-domains:}") + private String allowedDomains; + @SuppressWarnings({ "rawtypes", "unchecked" }) @Bean @ConditionalOnProperty(value = "xss.enabled", havingValue = "true") @@ -43,6 +48,23 @@ public class FilterConfig return registration; } + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Bean + @ConditionalOnProperty(value = "referer.enabled", havingValue = "true") + public FilterRegistrationBean refererFilterRegistration() + { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setDispatcherTypes(DispatcherType.REQUEST); + registration.setFilter(new RefererFilter()); + registration.addUrlPatterns(Constants.RESOURCE_PREFIX + "/*"); + registration.setName("refererFilter"); + registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE); + Map initParameters = new HashMap(); + initParameters.put("allowedDomains", allowedDomains); + registration.setInitParameters(initParameters); + return registration; + } + @SuppressWarnings({ "rawtypes", "unchecked" }) @Bean public FilterRegistrationBean someFilterRegistration()