From f0346b3defcc7d185f34a0d5e016abebe9c04ef4 Mon Sep 17 00:00:00 2001 From: RuoYi Date: Tue, 2 Sep 2025 11:31:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=98=B2=E7=9B=97=E9=93=BE?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application.yml | 7 ++ .../ruoyi/common/filter/RefererFilter.java | 77 +++++++++++++++++++ .../ruoyi/framework/config/FilterConfig.java | 22 ++++++ 3 files changed, 106 insertions(+) create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/filter/RefererFilter.java diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index fd57d557c..08fbc05f7 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -127,6 +127,13 @@ springdoc: paths-to-match: '/**' packages-to-scan: com.ruoyi.web.controller.tool +# 防盗链配置 +referer: + # 防盗链开关 + enabled: false + # 允许的域名列表 + allowed-domains: localhost,127.0.0.1,ruoyi.vip,www.ruoyi.vip + # 防止XSS攻击 xss: # 过滤开关 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 000000000..ac9ed1638 --- /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 jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.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() + { + + } +} \ No newline at end of file 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 00b854c51..d2429a9c3 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()