通过判断请求Header中的Referer来防止伪造请求

本文介绍了一种通过在web.xml中配置REFERER过滤器来增强Web应用安全性的方式。该过滤器能够检查HTTP请求头中的REFERER字段,确保其来源合法,从而防止非法请求访问。

其实不会根本性的解决这个问题。

解决方法:

在web.xml中增加:

    <filter>
        <filter-name>refererFilter</filter-name>
        <filter-class>ltd.miku.web.securityenhance.xss.RefererFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>refererFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

然后RefererFilter的内容是:

import com.inspur.ssr.web.system.service.impl.ExpireSessionImpl;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

@Service
public class RefererFilter implements Filter
{
    private static final Logger logger = LoggerFactory.getLogger(RefererFilter.class);

    public void init(FilterConfig filterConfig) throws ServletException
    {
        logger.debug(" init {} but actually do nothing.", getClass().getName());
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException

    {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        String rawReferer = httpServletRequest.getHeader("referer");
        boolean legal = false;
        if (StringUtils.isBlank(rawReferer))
        {
            legal = true;
        }
        else
        {
            try
            {
                URL url = new URL(rawReferer);
                String clientIp = httpServletRequest.getRemoteAddr();
                String referIp = url.getHost();
                String localIp = httpServletRequest.getLocalAddr();

                if (StringUtils.equals(clientIp, referIp))
                {
                    legal = true;
                }
                if (StringUtils.equals("localhost", referIp) || StringUtils.equals("127.0.0.1", referIp) || StringUtils.equals(localIp, referIp))
                {
                    legal = true;
                }
            }
            catch (MalformedURLException e)
            {
                e.printStackTrace();
            }
        }

        if (!legal)
        {
            logger.warn(" illegal referer: {}", rawReferer);
            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
        }
        else
        {
            chain.doFilter(request, response);
        }

    }

    public void destroy()
    {
        logger.debug(" destroy {} but actually do nothing.", getClass().getName());
    }
}

虽然代码写的比较翔,但是好歹是能用的。。。。。↑↑↑↑↑↑注意有待优化,无法直接生产用↑↑↑↑↑
<think>我们正在讨论Java中HTTP请求头的Referer属性。根据用户的问题,我们需要解释Referer的作用和用法。引用[1]提到请求头包含客户端请求的相关信息,如用户代理、来源等。Referer正是表示请求来源的头部。引用[2]展示了在Servlet中如何通过HttpServletRequest对象获取Referer头,并用于校验。引用[3]则展示了使用RestTemplate时获取响应头的方法,但用户问题关注的是请求头,尤其是Referer。因此,我们将重点放在Referer请求头的解释和用法上。回答结构:1.解释Referer的作用2.说明在Java中如何获取Referer(主要使用HttpServletRequest)3.给出一个完整的使用示例4.注意事项同时,按照要求生成相关问题。</think>### Java HTTP请求Referer 属性详解 #### 一、Referer 属性的作用 Referer(注意拼写应为"Referrer",但HTTP规范保留"Referer"拼写)是HTTP请求头的重要字段,用于**标识当前请求的来源页面URL**。主要作用包括: 1. **来源追踪** 服务器可识别用户从哪个网页链接跳转而来,例如: - 用户点击A网站的链接访问B网站时,B网站收到的请求头中将包含: `Referer: https://www.site-a.com/page.html` 2. **防盗链机制** 保护资源(如图片/文件)不被第三方网站直接引用: ```java if (referer == null || !referer.contains("my-domain.com")) { response.sendError(403, "Forbidden hotlinking"); } ``` 3. **数据分析** 统计流量来源渠道(搜索引擎/社交媒体/广告等),例如: - `Referer: https://www.google.com/` 表示来自Google搜索 4. **跨站请求安全校验** 配合CSRF保护机制验证请求合法性[^2]。 #### 二、Java 中的获取方法 在Java Web开发中,主要通过`HttpServletRequest`对象获取: ```java // 在Servlet或Controller中 public void handleRequest(HttpServletRequest request) { // 获取Referer头信息 String referer = request.getHeader("Referer"); // 典型应用:来源校验 if (referer != null && referer.startsWith("https://trusted-domain.com")) { // 执行安全操作 } else { // 处理非法来源请求 } } ``` #### 三、使用注意事项 1. **隐私限制** - 浏览器在HTTPS→HTTP跳转或隐私模式下可能不发送Referer - 可通过`<meta name="referrer" content="no-referrer">`禁止发送 2. **安全校验局限** Referer可能被伪造,敏感操作需结合CSRF Token等机制增强安全[^2]。 3. **空值处理** 直接访问URL或从书签打开时Referer为`null`,代码需做判空处理。 #### 四、完整示例:资源防盗链 ```java @RestController public class ResourceController { @GetMapping("/protected-image") public ResponseEntity<byte[]> getImage(HttpServletRequest request) { String referer = request.getHeader("Referer"); // 校验来源是否为本站 if (referer == null || !referer.contains("my-website.com")) { return ResponseEntity.status(403).body("Access forbidden".getBytes()); } // 返回图片资源 byte[] image = Files.readAllBytes(Paths.get("image.png")); return ResponseEntity.ok() .header("Content-Type", "image/png") .body(image); } } ``` > **关键点说明**: > 当用户直接访问`/protected-image`或从外部网站请求时,将返回403错误;仅当从`my-website.com`域内发起请求时才返回图片资源[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值