0

0

如何使用Java设置Referer防盗链 Java根据来源设置访问权限示例

蓮花仙者

蓮花仙者

发布时间:2025-07-19 13:52:02

|

1054人浏览过

|

来源于php中文网

原创

要防止盗链,可以通过验证请求头中的 referer 字段来实现;1. 在 java 中可通过 servlet 或 filter 实现防盗链逻辑,在 servlet 中获取 referer 并判断是否符合预期来源,若不符合则返回 403 错误;2. 使用 filter 可在请求进入业务逻辑前统一拦截处理,适用于更通用的防盗链场景,并支持从配置文件中读取允许的 referer;3. 更严格的验证方式包括使用白名单和完整匹配 referer 值以提高安全性;4. 对于 referer 为空的情况,可根据业务策略选择允许访问、拒绝访问或提供降级方案如身份验证;5. 结合 spring security 可创建自定义 refererfilter 并集成到安全配置中,实现灵活且可配置的安全策略。

如何使用Java设置Referer防盗链 Java根据来源设置访问权限示例

直接设置 Referer 来防止盗链,本质上就是在服务器端验证请求头中的 Referer 字段。如果 Referer 不符合你的预期,就拒绝服务。Java 中实现这个并不复杂,但需要根据你的具体应用场景来细化。

如何使用Java设置Referer防盗链 Java根据来源设置访问权限示例

解决方案

核心思路是在你的 Servlet 或 Filter 中拦截请求,然后检查 request.getHeader("Referer") 的值。

立即学习Java免费学习笔记(深入)”;

如何使用Java设置Referer防盗链 Java根据来源设置访问权限示例

1. 使用 Servlet 实现

创建一个 Servlet,并在 doGetdoPost 方法中进行 Referer 检查。

如何使用Java设置Referer防盗链 Java根据来源设置访问权限示例
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/protectedResource")
public class ProtectedResourceServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String referer = request.getHeader("Referer");

        // 允许的来源
        String allowedReferer = "http://www.example.com";

        if (referer != null && referer.startsWith(allowedReferer)) {
            // 允许访问,返回资源
            response.getWriter().println("<h1>Welcome! This is your protected resource.</h1>");
        } else {
            // 拒绝访问
            response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied. Invalid Referer.");
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

这段代码首先获取 Referer,然后检查它是否以 http://www.example.com 开头。如果是,就返回资源;否则,返回 403 错误。

2. 使用 Filter 实现

Filter 可以在 Servlet 之前拦截请求,实现更通用的防盗链逻辑。

import java.io.IOException;
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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebFilter("/*") // 拦截所有请求
public class RefererFilter implements Filter {

    private String allowedReferer;

    public void init(FilterConfig fConfig) throws ServletException {
        allowedReferer = "http://www.example.com"; // 从配置文件读取
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        String referer = httpRequest.getHeader("Referer");

        if (referer != null && referer.startsWith(allowedReferer)) {
            chain.doFilter(request, response); // 继续处理请求
        } else {
            httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied. Invalid Referer.");
        }
    }

    public void destroy() {
        // cleanup
    }
}

Filter 的好处是可以配置拦截的 URL 模式,例如拦截所有请求("/*")或特定的目录。allowedReferer 可以从 web.xml 或其他配置文件中读取,更灵活。

3. 更严格的 Referer 验证

仅仅检查 Referer 是否以某个字符串开头可能不够安全,因为攻击者可以伪造 Referer。可以考虑:

  • 白名单: 维护一个允许的 Referer 列表,只允许列表中的 Referer 访问。
  • Referer 完整匹配: 要求 Referer 必须完全匹配某个值。

4. 处理 Referer 为空的情况

有些浏览器或用户可能会禁用 Referer 发送。你需要决定如何处理这种情况。是允许访问,还是拒绝?

if (referer == null || referer.isEmpty()) {
    // Referer 为空时的处理逻辑
    // 可以选择允许访问,或者拒绝访问
    // 例如:
    // chain.doFilter(request, response); // 允许
    // 或者
    // httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied. Referer is missing."); // 拒绝
}

注意事项:

  • Referer 可伪造: 这种方法并不能完全防止盗链,因为 Referer 可以被伪造。更可靠的防盗链方法包括使用签名 URL 或 token。
  • HTTPS: 确保你的网站使用 HTTPS,以防止 Referer 在传输过程中被篡改。

如何处理 Referer 为空的情况,以及没有 Referer 的请求?

处理 Referer 为空的情况需要根据你的业务逻辑和安全策略来决定。没有 Referer 的请求可能是用户直接在浏览器地址栏输入 URL,也可能是通过某些工具或设置禁用了 Referer 发送。

策略选择:

  1. 允许访问: 如果你的资源对所有人开放,或者你认为 Referer 防盗链只是一个辅助手段,那么可以允许 Referer 为空的请求访问。
  2. 拒绝访问: 如果你非常重视防盗链,并且认为没有 Referer 的请求可能是恶意访问,那么可以拒绝这些请求。
  3. 提供降级方案: 可以考虑提供一种降级方案,例如要求用户进行身份验证,或者显示一个验证码。

实现方式:

Zyro AI Image Upscaler
Zyro AI Image Upscaler

Zyro出品的AI图片放大工具

下载

在你的 Servlet 或 Filter 中,添加对 Referer 为空的判断。

String referer = request.getHeader("Referer");

if (referer == null || referer.isEmpty()) {
    // Referer 为空
    // 策略 1:允许访问
    // chain.doFilter(request, response);

    // 策略 2:拒绝访问
    // httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied. Referer is missing.");

    // 策略 3:提供降级方案
    // response.sendRedirect("/login"); // 跳转到登录页面
    // 或者
    // response.getWriter().println("Please enable Referer in your browser settings.");
} else {
    // Referer 不为空,进行正常的防盗链检查
    if (referer.startsWith(allowedReferer)) {
        chain.doFilter(request, response);
    } else {
        httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied. Invalid Referer.");
    }
}

示例:允许 Referer 为空的请求访问

String referer = request.getHeader("Referer");

if (referer == null || referer.isEmpty()) {
    // 允许 Referer 为空的请求访问
    chain.doFilter(request, response);
} else {
    // Referer 不为空,进行正常的防盗链检查
    if (referer.startsWith(allowedReferer)) {
        chain.doFilter(request, response);
    } else {
        httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied. Invalid Referer.");
    }
}

示例:拒绝 Referer 为空的请求访问

String referer = request.getHeader("Referer");

if (referer == null || referer.isEmpty()) {
    // 拒绝 Referer 为空的请求访问
    httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied. Referer is missing.");
} else {
    // Referer 不为空,进行正常的防盗链检查
    if (referer.startsWith(allowedReferer)) {
        chain.doFilter(request, response);
    } else {
        httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied. Invalid Referer.");
    }
}

最佳实践:

  • 用户体验: 在拒绝访问时,提供友好的提示信息,告诉用户为什么无法访问,以及如何解决问题。
  • 日志记录: 记录 Referer 为空的请求,以便分析和排查问题。
  • 可配置性: 将处理 Referer 为空策略配置化,方便根据实际情况进行调整。

如何结合 Spring Security 使用 Referer 防盗链?

Spring Security 提供了强大的安全控制功能,可以与 Referer 防盗链结合使用,实现更灵活和可配置的安全策略。

1. 创建自定义 Filter

首先,创建一个自定义的 Filter,用于检查 Referer。这个 Filter 需要继承 OncePerRequestFilter,确保每个请求只被执行一次。

import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class RefererFilter extends OncePerRequestFilter {

    private final Set<String> allowedReferers = new HashSet<>();
    private final AntPathRequestMatcher requestMatcher;

    public RefererFilter(String[] allowedReferers, String path) {
        this.allowedReferers.addAll(Arrays.asList(allowedReferers));
        this.requestMatcher = new AntPathRequestMatcher(path);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if (!requestMatcher.matches(request)) {
            filterChain.doFilter(request, response);
            return;
        }

        String referer = request.getHeader("Referer");

        if (referer != null && allowedReferers.stream().anyMatch(referer::startsWith)) {
            filterChain.doFilter(request, response);
        } else {
            response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied. Invalid Referer.");
        }
    }
}

在这个 Filter 中,allowedReferers 是允许的 Referer 列表,requestMatcher 用于匹配需要进行 Referer 检查的 URL。

2. 配置 Spring Security

在 Spring Security 的配置类中,将自定义的 Filter 添加到 Filter Chain 中。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public RefererFilter refererFilter() {
        String[] allowedReferers = {"http://www.example.com", "https://www.example.com"};
        return new RefererFilter(allowedReferers, "/protected/**"); // 对 /protected/** 下的资源进行 Referer 检查
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authz -> authz
                .requestMatchers("/public/**").permitAll() // 允许访问 /public/** 下的资源
                .anyRequest().authenticated() // 其他请求需要认证
            )
            .addFilterBefore(refererFilter(), UsernamePasswordAuthenticationFilter.class); // 在 UsernamePasswordAuthenticationFilter 之前添加 RefererFilter

        return http.build();
    }
}

在这个配置中,refererFilter() 方法创建了一个 RefererFilter 实例,并设置了允许的 Referer 列表和需要进行 Referer 检查的 URL 模式。addFilterBefore() 方法将 RefererFilter 添加到 Filter Chain 中,确保它在 UsernamePasswordAuthenticationFilter 之前执行。

3. 配置允许的 Referer

可以将允许的 Referer 列表配置在 application.propertiesapplication.yml 文件中,方便修改和管理。

allowed.referers=http://www.example.com,https://www.example.com

然后在 RefererFilter 中读取这些配置。

4. 处理异常情况

可以自定义一个 AuthenticationEntryPoint,用于处理 Referer 验证失败的情况,例如跳转到错误页面或返回特定的错误信息。

优点:

  • 集中管理: Spring Security 提供了集中的安全配置管理,方便维护和扩展。
  • 灵活性: 可以根据不同的 URL 模式配置不同的 Referer 检查策略。
  • 可配置性: 可以将允许的 Referer 列表配置在配置文件中,方便修改和管理。
  • 与其他安全功能集成: 可以与其他 Spring Security 的安全功能(例如认证、授权)集成使用,实现更全面的安全保护。

注意事项:

  • Filter 顺序: 确保 RefererFilter 在其他需要 Referer 信息的 Filter 之前执行。
  • 配置正确性: 确保 Spring Security 的配置正确,避免出现意外的安全漏洞。
  • 测试: 对 Referer 防盗链功能进行充分的测试,确保其能够正常工作。

通过结合 Spring Security 使用 Referer 防盗链,可以实现更灵活、可配置和安全的安全策略。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

155

2025.08.06

Java Spring Security 与认证授权
Java Spring Security 与认证授权

本专题系统讲解 Java Spring Security 框架在认证与授权中的应用,涵盖用户身份验证、权限控制、JWT与OAuth2实现、跨站请求伪造(CSRF)防护、会话管理与安全漏洞防范。通过实际项目案例,帮助学习者掌握如何 使用 Spring Security 实现高安全性认证与授权机制,提升 Web 应用的安全性与用户数据保护。

88

2026.01.26

servlet生命周期
servlet生命周期

Servlet生命周期是指Servlet从创建到销毁的整个过程。本专题为大家提供servlet生命周期的各类文章,大家可以免费体验。

393

2023.08.08

pdf怎么转换成xml格式
pdf怎么转换成xml格式

将 pdf 转换为 xml 的方法:1. 使用在线转换器;2. 使用桌面软件(如 adobe acrobat、itext);3. 使用命令行工具(如 pdftoxml)。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1945

2024.04.01

xml怎么变成word
xml怎么变成word

步骤:1. 导入 xml 文件;2. 选择 xml 结构;3. 映射 xml 元素到 word 元素;4. 生成 word 文档。提示:确保 xml 文件结构良好,并预览 word 文档以验证转换是否成功。想了解更多xml的相关内容,可以阅读本专题下面的文章。

2119

2024.08.01

xml是什么格式的文件
xml是什么格式的文件

xml是一种纯文本格式的文件。xml指的是可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。想了解更多相关的内容,可阅读本专题下面的相关文章。

1167

2024.11.28

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6604

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

842

2023.09.14

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

4

2026.03.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.3万人学习

C# 教程
C# 教程

共94课时 | 11.1万人学习

Java 教程
Java 教程

共578课时 | 80.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号