Asp.Net Core 通过中间件防止图片盗链
一、原理
要实现防盗链,我们就必须先理解盗链的实现原理,提到防盗链的实现原理就不得不从HTTP协议说起,在HTTP协议中,有一个表头字段叫referer,采用URL的格式来表示从哪儿链接到当前的网页或文件。换句话说,通过referer,网站可以检测目标网页访问的来源网页,如果是资源文件,则可以跟踪到显示它的网页地址。有了referer跟踪来源就好办了,这时就可以通过技术手段来进行处理,一旦检测到来源不是本站即进行阻止或者返回指定的页面。如果想对自己的网站进行防盗链保护,则需要针对不同的情况进行区别对待。
如果网站服务器用的是apache,那么使用apache自带的Url Rewrite功能可以很轻松地防止各种盗链,其原理也是检查refer,如果refer的信息来自其他网站则重定向到指定图片或网页上。
如果服务器使用的是IIS的话,则需要通过第三方插件来实现防盗链功能了,现在比较常用的一款产品叫做ISAPI_Rewrite,可以实现类似于apache的防盗链功能。另外对于论坛来说还可以使用“登录验证”的方法进行防盗链。
二、实现防盗链
现在让我们在ASP.NET Core中实现防盗链技术来保护我们的应用程序和站点文件。这就要通过ASP.NET Core中的中间件技术,监听并处理所有传入的请求,检查这些请求是不是来自我们的应用程序。
让我们来创建这个防盗链的中间件程序:
public class HotlinkingPreventionMiddleware
{
private readonly string _wwwrootFolder;
private readonly RequestDelegate _next; public HotlinkingPreventionMiddleware(RequestDelegate next, IHostingEnvironment env)
{
_wwwrootFolder = env.WebRootPath;
_next = next;
} public async Task Invoke(HttpContext context)
{
var applicationUrl = $"{context.Request.Scheme}://{context.Request.Host.Value}";
var headersDictionary = context.Request.Headers;
var urlReferrer = headersDictionary[HeaderNames.Referer].ToString(); if(!string.IsNullOrEmpty(urlReferrer) && !urlReferrer.StartsWith(applicationUrl))
{
var unauthorizedImagePath = Path.Combine(_wwwrootFolder,"Images/Unauthorized.png"); await context.Response.SendFileAsync(unauthorizedImagePath);
} await _next(context);
}
}
在这个中间件中我们可以看到ASP.NET Core中的Request对象并没有对Referrer进行封装,想获取Referrer,就要通过HTTP头信息(Headers)进行访问。
一般都要有一个IApplicationBuilder扩展:
public static class BuilderExtensions
{
public static IApplicationBuilder UseHotlinkingPreventionMiddleware(this IApplicationBuilder app)
{
return app.UseMiddleware();
}
}
最后,使用它只需要在Configure函数中调用,上面的扩展函数。
app.UseHotlinkingPreventionMiddleware();
三、真能防?
如何突破防盗链?针对检查refer的方式,可以在页面中间件里面先进入目的地址的另外一个页面在转到目的页面即可,这样页面的refer就是目的站点自己的,如此,即做到突破。这方面可以使用的工具很多,尤其是成熟的web项目测试包,如HtmlUnit,直接在请求中设置refer都是可以的。
如果盗用网站是 https 的 protocol,而图片链接是 http 的话,则从 https 向 http 发起的请求会因为安全性的规定,而不带 referer,从而实现防盗链的绕过。
最后,我只能说这种方式,只能在一定程度上进行防御,不可能杜绝所有的攻击,还是建议使用成熟服务器应用的方案,比如Nginx。
GitHub:https://github.com/maxzhang1985/YOYOFx 如果觉还可以请Star下, 欢迎一起交流。
.NET Core 开源学习群: 214741894
Asp.Net Core 通过中间件防止图片盗链的更多相关文章
- Asp.Net Core 通过自定义中间件防止图片盗链的实例(转)
一.原理 要实现防盗链,我们就必须先理解盗链的实现原理,提到防盗链的实现原理就不得不从HTTP协议说起,在HTTP协议中,有一个表头字段叫referer,采用URL的格式来表示从哪儿链接到当前的网页或 ...
- 转:【译】Asp.net MVC 利用自定义RouteHandler来防止图片盗链
[译]Asp.net MVC 利用自定义RouteHandler来防止图片盗链 你曾经注意过在你服务器请求日志中多了很多对图片资源的请求吗?这可能是有人在他们的网站中盗链了你的图片所致,这会占用你 ...
- 如何传递参数给ASP.NET Core的中间件(Middleware)
问题描述 当我们在ASP.NET Core中定义和使用中间件(Middleware)的时候,有什么好的办法可以给中间件传参数吗? 解决方案 在ASP.NET Core项目中添加一个POCO类来传递参数 ...
- asp.net core mvc 中间件之WebpackDevMiddleware
asp.net core mvc 中间件之WebpackDevMiddleware WebpackDevMiddleware中间件主要用于开发SPA应用,启用Webpack,增强网页开发体验.好吧,你 ...
- asp.net core mvc 中间件之路由
asp.net core mvc 中间件之路由 路由中间件 首先看路由中间件的源码 先用httpContext实例化一个路由上下文,然后把中间件接收到的路由添加到路由上下文的路由集合 然后把路由上下文 ...
- 如何在ASP.NET Core自定义中间件中读取Request.Body和Response.Body的内容?
原文:如何在ASP.NET Core自定义中间件中读取Request.Body和Response.Body的内容? 文章名称: 如何在ASP.NET Core自定义中间件读取Request.Body和 ...
- asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密。
原文:asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密. GitHub demo https://github.com/zhanglilong23/Asp.NetCore. ...
- ASP.NET Core路由中间件[3]: 终结点(Endpoint)
到目前为止,ASP.NET Core提供了两种不同的路由解决方案.传统的路由系统以IRouter对象为核心,我们姑且将其称为IRouter路由.本章介绍的是最早发布于ASP.NET Core 2.2中 ...
- ASP.NET Core路由中间件[2]: 路由模式
一个Web应用本质上体现为一组终结点的集合.终结点则体现为一个暴露在网络中可供外界采用HTTP协议调用的服务,路由的作用就是建立一个请求URL模式与对应终结点之间的映射关系.借助这个映射关系,客户端可 ...
随机推荐
- .NET面试题系列[0] - 写在前面
.NET面试题系列目录 .NET面试题系列[1] - .NET框架基础知识(1) .NET面试题系列[2] - .NET框架基础知识(2) .NET面试题系列[3] - C# 基础知识(1) .NET ...
- ASP.Net请求处理机制初步探索之旅 - Part 5 ASP.Net MVC请求处理流程
好听的歌 我一直觉得看一篇文章再听一首好听的歌,真是种享受.于是,我在这里嵌入一首好听的歌,当然你觉得不想听的话可以点击停止,歌曲 from 王菲 <梦中人>: --> 开篇:上一篇 ...
- spring-boot 和 docker 集成
描述 java 的 Spring是一个很火的框架,Spring boot 这个也不用说了,Docker 近年也很火热, 本文就介绍下我在 Spring boot + Docker的集成一些经验 :) ...
- Android学习第二天-android常用命令
上一篇文章中,我们重点讲解了adb的常用命令,下面我们一起来看看其它常用的命令 2 android 2.1 查看机器上所有已经安装的Android版本和AVD设备 2.1.1查看机器上已经安装的AVD ...
- enum操作--获取枚举里的最大值
一个应用系统,如果程序里没有任何enum的使用,我认为它的可读性是有待商榷的. 求枚举里的最大/最小枚举值, 其实是对Array进行操作: enum EnumTest { ddd = , eee } ...
- Java针对数据库增删改查代码
package com.bank.abc; import java.beans.PropertyVetoException; import java.sql.Connection; import ja ...
- 面向属性的CSS命名
自从开始做前端开发以来,我发现在开发页面的时候,总是有一个问题十分影响自己的开发效率,这个问题就是css的命名,主要是指css类选择器的命名.这个问题主要体现在:第一,有的内容你压根想不出用什么名字来 ...
- 初学者--bootstrap(三)下载与安装----在路上(7)
----------------------------------------对于学习与工作者来说用压缩版,若是研究框架则用源代码---------------------------------- ...
- 微信蓝牙设备开发教程之获取设备deviceid和二维码(3)
文章转载地址 http://www.vxzsk.com/87.html 设备授权 调用 设备授权新接口 ,获取deviceid和二维码,然后利用获取到的deviceid更新设备属性(如mac地址, ...
- [转]关于typedef的用法总结
不管实在C还是C++代码中,typedef这个词都不少见,当然出现频率较高的还是在C代码中.typedef与#define有些相似,但更多的是不同,特别是在一些复杂的用法上,就完全不同了,看了网上一些 ...