springboot实现文件防盗链设计

shigen坚持更新文章的博客写手,擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长,分享认知,留住感动。
个人IP:shigen

👋👋👋hello,伙伴们好久不见,最近shigen遇到了很多的事情,现在算是安顿好了,也可以开始技术分享了。但是分享的频率的话,肯定会比之前低的很多,因为我也要正式的学习新的技术了。

来今天的正题:springboot实现图片防盗链。可能看起来场景比较抽象,这里shigen给出之前的一个例子:对象存储服务的流量被盗刷了,当时官方给的解决方案包括我后来采用的方式就是referer的限制。

referer的限制

后来我的对象存储服务的流量就正常了。那今天我也是好奇这个用springboot怎么实现。在接下来的内容中,我将会着重分享我的设计。

首先了解一下Referer是什么吧。

什么是Referer

这里告别充满广告和垃圾网站的搜索引擎,直接GPT查询:

Referer(来源)是HTTP头部字段之一,用于指示客户端是从哪个页面跳转或发起请求的。当客户端(通常是浏览器)向服务器发送请求时,它会在HTTP头部中包含 Referer 字段,告诉服务器请求的来源页面的URL。这个字段可以帮助服务器了解请求的上下文和用户行为,有助于进行数据分析、安全检查等操作。

也就是说请求一个资源的时候,浏览器的请求头信息中会带上Referer字段标示出当下的请求的上一个请求是什么地方来的。

那基于这个原理,我们就可以设计出自己的防盗链。

java代码的设计

基础版

假设我们的springboot项目中可以直接通过http请求访问到某个路径下的资源。我们先这样的尝试吧。我们的配置肯定要实现WebMvcConfigurer这个接口,实现资源的映射。那我就直接展示我的代码:

@Configuration
@EnableWebMvc
@Slf4j
public class MvcConfig implements WebMvcConfigurer {/*** 静态资源保存目录*/public static final String FILE_RESOURCE_PATH = "file:" + System.getProperty("user.dir") + "/files/";@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {log.error("静态资源保存目录:{}", FILE_RESOURCE_PATH);registry.addResourceHandler("/files/**").addResourceLocations(FILE_RESOURCE_PATH);}
}

其实我们最终实现的文件路径就是项目根路径/files/文件夹的全部文件。

这样我们就可以通过http请求访问了。

http访问静态资源

但是,明显的我们的资源不是很安全。因为任意来源、任何人都可以访问到它。那我们限制来源的话,这个时候Referer就可以派上用场了。

升级版

升级版本,我们就需要统一拦截一下请求,看看请求头中是否包含Referer信息,且是我们约定的Referer。这样才能判定是正常的请求,进行流量的放行,否则的话就是要去拦截。

接下来先去设计一个拦截器:

@Slf4j
@Component
public class ResourceInterceptor extends HandlerInterceptorAdapter {@Resourceprivate ReferConfig referConfig;/*** 匹配的文件种类*/private static final String FILE_REGEX = "\\.(html|css|js|jpg|jpeg|png|gif|bmp|svg|pdf|doc|docx|xls|xlsx|ppt|pptx|mp4|mov)$";private static final Pattern FILE_REGEX_PATTERN = Pattern.compile(FILE_REGEX, Pattern.CASE_INSENSITIVE);@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 获取请求的 URLString requestUrl = request.getRequestURL().toString();log.info("requestUrl:{}", requestUrl);// 检查是否是静态资源请求if (referConfig.isEnabled() && isStaticResource(requestUrl)) {// 检查防盗链策略if (!isValidReferer(request)) {response.setStatus(HttpServletResponse.SC_FORBIDDEN);return false;}}return true;}/*** 正则验证请求的资源** @param url 请求资源* @return 是否匹配*/private boolean isStaticResource(String url) {return FILE_REGEX_PATTERN.matcher(url).find();}/*** 检查 Referer 头,判断请求是否合法** @param request 请求* @return 是否是合法请求*/private boolean isValidReferer(HttpServletRequest request) {String referer = request.getHeader("Referer");return CollectionUtil.contains(referConfig.getAllowedOrigins(), referer);}
}

具体的业务逻辑的验证都在注释里,这里需要注意:

  1. 关于Referer的配置最好写成动态的,便于后期的拓展
  2. 对于url的请求判断最好使用正则表达式,因为url本身请求的就是静态资源,但是后边带了其他的参数可能导致直接绕过

对于自定的配置类,shigen是这样的设计:

@Configuration
@ConfigurationProperties(prefix = "refer")
@Data
public class ReferConfig {/*** 是否开启防盗链拦截*/private boolean enabled;/*** 允许的Referer请求*/private List<String> allowedOrigins;}

接下来就是配置到拦截器上。

@Configuration
@EnableWebMvc
@Slf4j
public class MvcConfig implements WebMvcConfigurer {@Resourceprivate UserArgumentResolver userArgumentResolver;@Resourceprivate ResourceInterceptor resourceInterceptor;/*** 静态资源保存目录*/public static final String FILE_RESOURCE_PATH = "file:" + System.getProperty("user.dir") + "/files/";@Overridepublic void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {resolvers.add(userArgumentResolver);}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(resourceInterceptor).addPathPatterns("/**");}@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {log.error("静态资源保存目录:{}", FILE_RESOURCE_PATH);registry.addResourceHandler("/files/**").addResourceLocations(FILE_RESOURCE_PATH);}
}

待一切完成,我们这里再检查一下配置文件就可以正常的启动服务进行测试了。

refer:enabled: trueallowed-origins:- http://www.shigen.com

此时,我们再次在浏览器中直接访问:

浏览器中403

这时我们想要正常的访问,就得借助于接口测试工具了。

手动加上Referer

以上就是关于文件防盗链的设计分享,相关代码可参考:新增文件防盗链案例。

与shigen一起,每天不一样!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/838522.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git使用(1):介绍、克隆、推送

一、介绍与安装 1、Git是什么&#xff1f; Git是目前世界上最先进的分布式版本控制系统。工作原理 / 流程&#xff1a; workspace&#xff1a;工作区Index / Stage&#xff1a;暂存区Repository&#xff1a;仓库区&#xff08;或本地仓库&#xff09;Remote&#xff1a;远程仓…

智能防疫电梯模拟控制系统设计-设计说明书

设计摘要&#xff1a; 本设计是基于单片机的智能防疫电梯模拟控制系统&#xff0c;主要实现了多项功能。首先&#xff0c;系统进行无接触测温&#xff0c;如果温度正常则可以启动电梯运行&#xff0c;如果温度异常则电梯会报警提示有乘客体温异常&#xff0c;电梯不会运行。其…

Pencils Protocol 宣布再获合作伙伴 Galxe 的投资

近日&#xff0c;Scroll生态项目Penpad将品牌进一步升级为Pencils Protocol&#xff0c;全新升级后其不仅对LaunchPad平台进行了功能上的升级&#xff0c;同时其也进一步引入了Staking、Vault以及Shop等玩法&#xff0c;这也让Pencils Protocol的叙事方向不再仅限于LaunchPad&a…

BUUCTF靶场[MISC]荷兰宽带数据泄露、九连环

[MISC]荷兰宽带数据泄露 考点&#xff1a;查看路由器恢复丢失密码的文件 工具&#xff1a;RouterPassView——路由器密码查看工具 工具链接&#xff1a;https://routerpassview.en.lo4d.com/windows RouterPassView是一款老牌的路由器密码查看器&#xff0c;可以一键获取路…

[Kubernetes] kube-proxy 详解

文章目录 1.kube-proxy概述2.userspace模式3.iptables模式4.ipvs模式 1.kube-proxy概述 kube-proxy组件是用来实现service的请求转发&#xff0c;具体实现方式是kube-proxy运行在每个node上&#xff0c;通过watch监听API Server 中service资源的create&#xff0c;update&…

IPv6路由配置:ripng、ospfv3、静态路由

本次主要是对ipv6路由的配置&#xff0c;先了解ipv6&#xff0c;再进行实验配置 目录 一、&#x1f349; 什么是IPV6&#xff1f;&#x1f31f;IPv6的主要特点 二、&#x1f349;IPv6和IPv4的对比&#x1f31f; 共同点:&#x1f31f; IPv4的优缺点:&#x1f31f; IPv6的优缺点:…

Docker三剑客从0到1

一、docker三剑客介绍 使用"三剑客"可以帮助我们解决docker host维护,多容器编排部署,多个docker host集群的各个难题。 docker-machine 创建虚拟机 我们知道docker使用了linux的内核技术(namespace 资源隔离,cgroup资源限制等),那么如果我想在windows或Mac系统上…

按照官网引擎问题重新设置监控目录,仍然存在空三等待的问题怎么办?

答&#xff1a;任务目录和引擎目录设置一样&#xff0c;然后取消任务重新写入. 重建大师是一款专为超大规模实景三维数据生产而设计的集群并行处理软件&#xff0c;输入倾斜照片&#xff0c;激光点云&#xff0c;POS信息及像控点&#xff0c;输出高精度彩色网格模型&#xff0…

webpack生成模块关系依赖图示例:查看构建产物的组成部分 依赖关系图

npm i -D webpack-bundle-analyzer core-js babel-loaderwebpack.config.js const BundleAnalyzerPlugin require(webpack-bundle-analyzer).BundleAnalyzerPlugin; module.exports {entry: ./src/index.js,output: {filename: main.js,},// mode: production, // 或者 produ…

公共命名空间和RHP

概述 RHP的全称是&#xff1a;the little Robot that Helped me Program&#xff0c;帮我编程序的小机器人。 RHP必然存在&#xff0c;C语言的宏、C的模板&#xff0c;都是RHP&#xff1b;更复杂的例子&#xff0c;是lex和yacc&#xff0c;它们是制作程序的程序&#xff0c;也…

MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】

前言 做数仓开发离不开 SQL &#xff0c;写了很多 HQL 回头再看 MySQL 才发现&#xff0c;很多东西并不是 HQL 所独创的&#xff0c;而是几乎都来自于关系型数据库通用的 SQL&#xff1b;想到以后需要每天和数仓打交道&#xff0c;那么不管是 MySQL 还是 Oracle &#xff0c;都…

EDA设计学习笔记2:STM32F103C8T6最小系统板的仿绘

今日开始仿制练习一个STM32F103C8T6最小系统板&#xff0c;通过对这个最小系统板的仿制&#xff0c;达到对自己PCB设计的练习的目的&#xff0c;最终目标是自己设计出一块PCB&#xff0c;做一个OLED的桌面小摆件...... 也不知道画出来能不能用..... 目录 主控芯片的搜索与放置…

迷宫游戏(c++)

我们来玩一个迷宫游戏&#xff0c;尝试走一下面的迷宫。 迷宫游戏 我们用一个二维的字符数组来表示前面画出的迷宫&#xff1a; S**. .... ***T 其中字符S表示起点&#xff0c;字符T表示终点&#xff0c;字符*表示墙壁&#xff0c;字符.表示平地。你需要从S出发走到T&#xf…

React渲染流程

在 React 渲染分为两个阶段&#xff0c;Render 和 Commit&#xff0c;Render 是修改 React 组件的状态&#xff0c;把需要更新的组件标记为待更新&#xff0c;在 Commit 阶段将待更新的组件进行渲染并最终更新到浏览器的 Dom 树中。 Render 阶段是可以并执行操作的&#xff0c…

软件测试常见面试题合集(内附详细答案)

01 软件测试理论部分 1.1 测试概念 1. 请你分别介绍一下单元测试、集成测试、系统测试、验收测试、回归测试 单元测试&#xff1a;完成最小的软件设计单元&#xff08;模块&#xff09;的验证工作&#xff0c;目标是确保模块被正确的编码 集成测试&#xff1a;通过测试发现与…

猛兽派对是什么游戏 猛兽派对攻略大全 苹果电脑怎么玩《猛兽派对》?

猛兽派对是多人派对类型的游戏&#xff0c;该款游戏的动作基于物理原理设计的&#xff0c;体验游戏玩家可以选择自己喜欢的小动物角色参加派对&#xff0c;游戏内具有很多不同的关卡可供挑战。 在steam平台上&#xff0c;猛兽派对对应英文名称是PartyAnimals&#xff0c;官方正…

JVM内存模型最新面试题(持续更新)

问题&#xff1a;java中创建的对象一般放在哪里&#xff1f;(全流程包含从创建到回收) 回答 大部分对象在堆中&#xff0c;这个基本都知道&#xff1b; 少部分对象是会在栈中的&#xff0c;比如作用域不局限于方法内的方法内部变量&#xff0c;这类对象的特征一般就是生命周期…

opencv4.8.0 GPU版本各平台编译

一、opencv4.8.0 ubuntu22.04上编译&#xff1a; 用cmake进行编译,需要配置三次。选中world选项&#xff0c;输入opencv_contrib_module路径。 ubuntu22.04上编译&#xff1a; cmake \ -D CMAKE_BUILD_TYPERELEASE \ -D CMAKE_INSTALL_PREFIX/usr/local \ -D BUILD_opencv_p…

免费公有云轻量级云服务,支持免费云数据库和创建应用,支持多语言应用!

在今天这个数字化迅速发展的时代&#xff0c;选择一个高效、经济且功能全面的云平台对于任何大小的企业来说都是至关重要的。MemFire Cloud 作为市场上新兴的星级云服务提供商&#xff0c;以其免费的公有云服务和对多种编程语言的支持&#xff0c;提供了一站式解决方案&#xf…

51单片机超声波测距_液位检测_温度检测原理图PCB仿真代码

目录 实物图&#xff1a; PCB ​原理图​ 仿真图 ​编辑 程序 资料下载地址&#xff1a;51单片机超声波测距-液位检测-温度检测原理图PCB仿真代码 主控为stc89c52,通过ds18b20进行温度采集&#xff0c;超声波测距&#xff0c;距离不可以超过1m&#xff0c;通过按键可以设…