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中的中间件技术,监听并处理所有传入的请求,检查这些请求是不是来自我们的应用程序。

  让我们来创建这个防盗链的中间件程序:

        
  1. public class HotlinkingPreventionMiddleware

  2. {

  3.    private readonly string _wwwrootFolder;

  4.    private readonly RequestDelegate _next;

  5.    public HotlinkingPreventionMiddleware(RequestDelegate next, IHostingEnvironment env)

  6.    {

  7.        _wwwrootFolder = env.WebRootPath;

  8.        _next = next;

  9.    }

  10.    public async Task Invoke(HttpContext context)

  11.    {

  12.        var applicationUrl = $"{context.Request.Scheme}://{context.Request.Host.Value}";

  13.        var headersDictionary = context.Request.Headers;

  14.        var urlReferrer = headersDictionary[HeaderNames.Referer].ToString();

  15.        if(!string.IsNullOrEmpty(urlReferrer) && !urlReferrer.StartsWith(applicationUrl))

  16.        {

  17.            var unauthorizedImagePath = Path.Combine(_wwwrootFolder,"Images/Unauthorized.png");

  18.                

  19.            await context.Response.SendFileAsync(unauthorizedImagePath);

  20.        }

  21.            

  22.        await _next(context);

  23.    }

  24. }

 

  在这个中间件中我们可以看到ASP.NET Core中的Request对象并没有对Referrer进行封装,想获取Referrer,就要通过HTTP头信息(Headers)进行访问。

  一般都要有一个IApplicationBuilder扩展:

        
  1. public static class BuilderExtensions

  2. {

  3.    public static IApplicationBuilder UseHotlinkingPreventionMiddleware(this IApplicationBuilder app)

  4.    {

  5.        return app.UseMiddleware();

  6.    }

  7. }

  最后,使用它只需要在Configure函数中调用,上面的扩展函数。

        
  1. app.UseHotlinkingPreventionMiddleware();


三、真能防?

 

  如何突破防盗链?针对检查refer的方式,可以在页面中间件里面先进入目的地址的另外一个页面在转到目的页面即可,这样页面的refer就是目的站点自己的,如此,即做到突破。这方面可以使用的工具很多,尤其是成熟的web项目测试包,如HtmlUnit,直接在请求中设置refer都是可以的。 

  如果盗用网站是 https 的 protocol,而图片链接是 http 的话,则从 https 向 http 发起的请求会因为安全性的规定,而不带 referer,从而实现防盗链的绕过。

  最后,我只能说这种方式,只能在一定程度上进行防御,不可能杜绝所有的攻击,还是建议使用成熟服务器应用的方案,比如Nginx。

原文地址:http://www.cnblogs.com/maxzhang1985/p/6124936.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

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

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

相关文章

Java IO: 并发IO

转载自 Java IO: 并发IO译文链接 作者: Jakob Jenkov 译者: 李璟 有时候你可能需要并发地处理输入和输出。换句话说,你可能有超过一个线程处理输入和产生输出。比如,你有一个程序需要处理磁盘上的大量文件,这个任务可以通过并发操作提高性能…

Ajax基本案例详解之$.ajax的实现

最近在学Ajax&#xff0c;现在来分享一下基本ajax案例&#xff1a; 先来说说$.ajax的情况&#xff1a; 首先我们先来创建个index.jsp&#xff0c;在index.jsp里面我们写一个<script>标签&#xff0c;主要是引用jquery的环境&#xff0c;没有的童鞋可以来这里下载一下。 …

linux软件可以在所有发行版运行吗,Linux通用的跨发行版的3大软件包管理器

前言本文主要介绍Linux系统上通用的跨发行版的3大软件包管理器。Linux系统上的软件包管理可能非常令人困惑&#xff0c;尤其是对于新手&#xff0c;因为不同的Linux发行版使用不同的包管理系统。在大多数情况下&#xff0c;最令人困惑的部分是软件包依赖项的解析和管理。例如&a…

Java IO: 管道

转载自 Java IO: 管道 译文链接 作者: Jakob Jenkov 译者: 李璟(jlee381344197gmail.com) Java IO中的管道为运行在同一个JVM中的两个线程提供了通信的能力。所以管道也可以作为数据源以及目标媒介。 你不能利用管道与不同的JVM中的线程通信(不同的进程)。在概念上&#xf…

springboot yml里面配置list 日期日期格式的postMen 发送json

Value("#{${ipWhiteList.ips}.split(,)}") List<String> ipList; ipWhiteList:ips: 10.0.0.2,127.0.0.1日期个是的postMen 发送json { "multiple": 39, "tenantNo": 39, "endCheckNum": 39, "meterNo&qu…

Ajax基本案例详解之$.get的实现

前面我已经写过一篇ajax的$.ajax的实现了&#xff0c;其中html&#xff0c;css&#xff0c;doindex.jsp里面已经详细列出来了&#xff0c;这篇主要写的是$.get()的实现&#xff0c;其中html&#xff0c;css&#xff0c;doindex.jsp都和Ajax基本案例详解之$.get的实现 里面的…

Java IO: 文件

转载自 Java IO: 文件 译文链接 作者: Jakob Jenkov 译者: 李璟(jlee381344197gmail.com) 在Java应用程序中&#xff0c;文件是一种常用的数据源或者存储数据的媒介。所以这一小节将会对Java中文件的使用做一个简短的概述。这篇文章不会对每一个技术细节都做出解释&#xf…

SpringBoot运行原理初探

运行原理初探 其中它主要是依赖一个父项目&#xff0c;主要是管理项目的资源过滤及插件&#xff01; <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.5.RELEASE&…

一款全新的基于IntelliJ和ReSharper的跨平台.NET IDE

JetBrains Rider在今年一月份露面&#xff0c;后来的大部分时间被用在了内部早期预览版上&#xff0c;还没有为公开发布做好准备。而现在&#xff0c;我们可以下载早期预览版&#xff0c;并感受在IntelliJ平台上开发.NET是一种什么体验。早期预览版还存在一些问题&#xff0c;不…

mysql自动插入的时间不对 差8小时

MySQL插入时间差八小时问题的解决方法 更新时间&#xff1a;2019年12月15日 10:19:12 转载 作者&#xff1a;lankeren 这篇文章主要给大家介绍了关于MySQL插入时间差八小时问题的解决方法&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家学习或者使用MySQL具…

Ajax基本案例详解之$.post的实现

Ajax的post实现&#xff1a; 看这篇之前建议大家去看看前面两篇文章&#xff1a; 1.Ajax基本案例详解之$.ajax的实现 2.Ajax基本案例详解之$.get的实现 现在写一下$.post()里面的主要内容&#xff1a; $.post("doindex.jsp","email"$("#emai…

windows为什么把linux打败了,快二十年了,人们为什么还是没有抛弃 Windows 转向 Linux?...

原标题&#xff1a;快二十年了&#xff0c;人们为什么还是没有抛弃 Windows 转向 Linux&#xff1f;自伟大的 Linux 操作系统诞生以来&#xff0c; 许多网友都试图列举出 Linux 可能是更好选择的具体原因 &#xff0c;其中包括&#xff1a;Linux 上的更新速度很快&#xff0c;“…

Java IO 概述

转载自 Java IO 概述 译文链接 作者: Jakob Jenkov 译者: 李璟(jlee381344197gmail.com) 校对&#xff1a;方腾飞 在这一小节&#xff0c;我会试着给出Java IO(java.io)包下所有类的概述。更具体地说&#xff0c;我会根据类的用途对类进行分组。这个分组将会使你在未来的工…

ASP.NET Core WebListener 服务器

WebListener是一个只能运行在Windows上的ASP.NET Core web服务器&#xff0c;基于Http.Sys内核模块驱动构建。在不借助IIS作为反向代理服务器的情况下&#xff0c;WebListener可以替代Kestrel用来与直接与互联网相连。实际上&#xff0c;WebListener不能和IIS或IIS Express一起…

git删除本地分支、删除远程分支 复制分支

git删除本地分支、删除远程分支 It_BeeCoder 2019-05-15 09:47:20 80268 收藏 15 展开 https://blog.csdn.net/lihua5419/article/details/81706905 1、查看所有分支 git branch -a 2、查看当前所在分支 git branch 3、删除本地的bug_xzx分支 git branch -d bug_xzx 4…

kotlin能用嵌入式linux,Kotlin在项目中的应用和踩过的坑

应用空类型安全Kotlin引入了可空类型(用&#xff1f;标识)&#xff0c;在编译期杜绝了可空类型直接调用方法的可能。var a: String "abc"a null // 编译错误var b: String? "abc"b null // okval l a.lengthval l b.length // 错误&#xff1a;变量…

ASP.NET Core的Kestrel服务器

Kestrel是一个基于libuv的跨平台ASP.NET Core web服务器&#xff0c;libuv是一个跨平台的异步I/O库。ASP.NET Core模板项目使用Kestrel作为默认的web服务器。 Kestrel支持以下功能&#xff1a; HTTPS用于启用不透明升级的WebSockets位于Nginx之后的高性能Unix sockets Kestrel …

RandomAccessFile

转载自 RandomAccessFile RandomAccessFile是用来访问那些保存数据记录的文件的&#xff0c;你就可以用seek( )方法来访问记录&#xff0c;并进行读写了。这些记录的大小不必相同&#xff1b;但是其大小和位置必须是可知的。但是该类仅限于操作文件。 RandomAccessFile不属于I…