ASP.NET Core 2.1 : 十四.静态文件与访问授权、防盗链
我的网站的图片不想被公开浏览、下载、盗链怎么办?本文主要通过解读一下ASP.NET Core对于静态文件的处理方式的相关源码,来看一下为什么是wwwroot文件夹,如何修改或新增一个静态文件夹,为什么新增的文件夹名字不会被当做controller处理?访问授权怎么做?(ASP.NET Core 系列目录)
一、静态文件夹
所谓静态文件,直观的说就是wwwroot目录下的一些直接提供给访问者的文件,例如css,图片、js文件等。 当然这个wwwroot目录是默认目录,
这个是在Main->CreateDefaultBuilder的时候做了默认设置。
public static class HostingEnvironmentExtensions
{
public static void Initialize(this IHostingEnvironment hostingEnvironment, string contentRootPath, WebHostOptions options)
{
//省略部分代码
var webRoot = options.WebRoot;
if (webRoot == null)
{
// Default to /wwwroot if it exists.
var wwwroot = Path.Combine(hostingEnvironment.ContentRootPath, "wwwroot");
if (Directory.Exists(wwwroot))
{
hostingEnvironment.WebRootPath = wwwroot;
}
}
else
{
hostingEnvironment.WebRootPath = Path.Combine(hostingEnvironment.ContentRootPath, webRoot);
}
//省略部分代码
}
}
二、处理方式
前文关于中间件部分说过,在Startup文件中,有一个 app.UseStaticFiles() 方法的调用,这里是将静态文件的处理中间件作为了“处理管道”的一部分,
并且这个中间件是写在 app.UseMvc 之前, 所以当一个请求进来之后, 会先判断是否为静态文件的请求,如果是,则在此做了请求处理,这时候请求会发生短路,不会进入后面的mvc中间件处理步骤。
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
} app.UseStaticFiles(); app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
三、新增静态文件目录
除了这个默认的wwwroot目录,需要新增一个目录来作为静态文件的目录,可以Startup文件的 app.UseStaticFiles() 下面继续use,例如下面代码
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "NewFilesPath")),
RequestPath = "/NewFiles"
});
含义就是指定应用程序目录中的一个名为“NewFilesPath”的文件夹,将它也设置问静态文件目录, 而这个目录的访问路径为"/NewFiles"。
例如文件夹"NewFilesPath"下面有一个test.jpg, 那么我们可以通过这样的地址来访问它:http://localhost:64237/NewFiles/test.jpg。
四、中间件的处理方式
静态文件的处理中间件为StaticFileMiddleware,主要的处理方法 Invoke 代码如下
public async Task Invoke(HttpContext context)
{
var fileContext = new StaticFileContext(context, _options, _matchUrl, _logger, _fileProvider, _contentTypeProvider); if (!fileContext.ValidateMethod())
{
_logger.LogRequestMethodNotSupported(context.Request.Method);
}
else if (!fileContext.ValidatePath())
{
_logger.LogPathMismatch(fileContext.SubPath);
}
else if (!fileContext.LookupContentType())
{
_logger.LogFileTypeNotSupported(fileContext.SubPath);
}
else if (!fileContext.LookupFileInfo())
{
_logger.LogFileNotFound(fileContext.SubPath);
}
else
{
// If we get here, we can try to serve the file
fileContext.ComprehendRequestHeaders();
switch (fileContext.GetPreconditionState())
{
case StaticFileContext.PreconditionState.Unspecified:
case StaticFileContext.PreconditionState.ShouldProcess:
if (fileContext.IsHeadMethod)
{
await fileContext.SendStatusAsync(Constants.Status200Ok);
return;
}
try
{
if (fileContext.IsRangeRequest)
{
await fileContext.SendRangeAsync();
return;
}
await fileContext.SendAsync();
_logger.LogFileServed(fileContext.SubPath, fileContext.PhysicalPath);
return;
}
catch (FileNotFoundException)
{
context.Response.Clear();
}
break;
case StaticFileContext.PreconditionState.NotModified:
_logger.LogPathNotModified(fileContext.SubPath);
await fileContext.SendStatusAsync(Constants.Status304NotModified);
return; case StaticFileContext.PreconditionState.PreconditionFailed:
_logger.LogPreconditionFailed(fileContext.SubPath);
await fileContext.SendStatusAsync(Constants.Status412PreconditionFailed);
return; default:
var exception = new NotImplementedException(fileContext.GetPreconditionState().ToString());
Debug.Fail(exception.ToString());
throw exception;
}
}
await _next(context);
}
当HttpContext进入此中间件后会尝试封装成StaticFileContext, 然后对其逐步判断,例如请求的URL是否与设置的静态目录一致, 判断文件是否存在,判断文件类型等,
若符合要求 ,会进一步判断文件是否有修改等。
五、静态文件的授权管理
默认情况下,静态文件是不需要授权,可以公开访问的。
因为即使采用了授权, app.UseAuthentication(); 一般也是写在 app.UseStaticFiles() 后面的,那么如果我们想对其进行授权管理,首先想到可以改写 StaticFileMiddleware 这个中间件,
在其中添加一些自定义的判断条件,但貌似不够友好。而且这里只能做一些大类的判断,比如请求的IP地址是否在允许范围内这样的还行,如果要根据登录用户的权限来判断(比如用户只能看到自己上传的图片)就不行了,
因为权限的判断写在这个中间件之后。所以可以通过Filter的方式来处理,首先可以在应用目录中新建一个"images"文件夹, 而这时就不要把它设置为静态文件目录了,这样这个"images"目录的文件默认情况下是不允许访问的,
然后通过Controller返回文件的方式来处理请求,如下代码所示
[Route("api/[controller]")]
[AuthorizeFilter]
public class FileController : Controller
{
[HttpGet("{name}")]
public FileResult Get(string name)
{
var file = Path.Combine(Directory.GetCurrentDirectory(), "images", name);
return PhysicalFile(file, "application/octet-stream");
}
}
在AuthorizeFilter中进行相关判断,代码如下
public class AuthorizeFilter: ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context); if (context.RouteData.Values["controller"].ToString().ToLower().Equals("file"))
{
bool isAllow = false;//在此进行一系列访问权限验证,如果失败,返回一个默认图片,例如logo或不允许访问的提示图片 if (!isAllow)
{
var file = Path.Combine(Directory.GetCurrentDirectory(), "images", "default.png"); context.Result = new PhysicalFileResult(file, "application/octet-stream"); }
}
}
}
ASP.NET Core 2.1 : 十四.静态文件与访问授权、防盗链的更多相关文章
- 15.ASP.NET Core 应用程序中的静态文件中间件
在这篇文章中,我将向大家介绍,如何使用中间件组件来处理静态文件.这篇文章中,我们讨论下面几个问题: 在ASP.NET Core中,我们需要把静态文件存放在哪里? 在ASP.NET Core中 wwwr ...
- centos LAMP第二部分apache配置 下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转 配置apache的访问日志 配置静态文件缓存 配置防盗链 访问控制 apache rewrite 配置开机启动apache tcpdump 第二十节课
centos LAMP第二部分apache配置 下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转 配置apache的访问日志 配置静态文件缓存 配置防盗链 ...
- asp.net core 教程(七)-异常处理、静态文件
Asp.Net Core-异常处理 Asp.Net Core-异常处理 在这一章,我们将讨论异常和错误处理.当 ASP.NET Core应用程序中发生错误时,您可以以各种不同的方式来处理.让我们来看看 ...
- [小技巧]ASP.NET Core中如何预压缩静态文件
原文地址:Pre-compressed static files with ASP.NET Core 作者:Gunnar Peipman 译者:Lamond Lu 译文:https://www.cnb ...
- Asp .Net core 2 学习笔记(3) —— 静态文件
这个系列的初衷是便于自己总结与回顾,把笔记本上面的东西转移到这里,态度不由得谨慎许多,下面是我参考的资源: ASP.NET Core 中文文档目录 官方文档 记在这里的东西我会不断的完善丰满,对于文章 ...
- ASP.NET Core 1.0基础之静态文件处理
来源 这些HTML , CSS files, image files, 和JavaScript这些静态文件,是ASP.NET能够直接响应给客户端的.本文详述下ASP.NET和静态文件的关系. Serv ...
- ASP.NET Core 2.2 十九. 你扔过来个json,我怎么接
原文:ASP.NET Core 2.2 十九. 你扔过来个json,我怎么接 前文说道了Action的激活,这里有个关键的操作就是Action参数的映射与模型绑定,这里即涉及到简单的string.in ...
- ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案 try.dot.net 的正确使用姿势 .Net NPOI 根据excel模板导出excel、直接生成excel .Net NPOI 上传excel文件、提交后台获取excel里的数据
ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案 ASP.NET Core 从2.2版本开始,采用了一个新的名为Endpoint的路由方案,与原来的方案在使用上差别不 ...
- ExpandoObject与DynamicObject的使用 RabbitMQ与.net core(一)安装 RabbitMQ与.net core(二)Producer与Exchange ASP.NET Core 2.1 : 十五.图解路由(2.1 or earler) .NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了
ExpandoObject与DynamicObject的使用 using ImpromptuInterface; using System; using System.Dynamic; names ...
随机推荐
- GitHub开源:SQLite 增强组件 Sheng.SQLite.Plus
Github:https://github.com/iccb1013/Sheng.SQLite.Plus Sheng.SQLite.Plus 是一个对直接使用 ADO.NET 方式操作 SQLite ...
- 在java中怎样实现多线程?线程的4种状态
一.在java中怎样实现多线程? extends Thread implement Runnable 方法一:继承 Thread 类,覆盖方法 run(),我们在创建的 Thread 类的子类中重写 ...
- Android 开发学习资源汇总
下面这些资源对Android开发来说是很有帮助的! 1. 在线代码运行工具 地址:https://tool.lu/coderunner/ 说明:此工具站能在线运行C.C++.Java,基本能满足相关基 ...
- SUSE12SP3-Mycat(2)Schema.xml配置详解
简介 Schema.xml 作为 MyCat 中重要的配置文件之一,管理着 MyCat 的逻辑库.表.分片规则.DataNode 以及 DataSource.弄懂这些配置,是正确使用 MyCat 的前 ...
- 开放windows服务器端口-----以打开端口8080为例
[转载]原文地址:https://blog.csdn.net/spt_dream/article/details/75014619 本文记录两个内容: 1.win7下打开端口 2.服务器(2003或者 ...
- Servlet不再是烦恼
Servlet 一.什么是Servlet? Servlet是在服务器上运行的小程序,也就是一个Java类,但比较特殊,不需要new,自动就可以运行.也有创建.垃圾回收和销毁过程.Servlet是Jav ...
- markdown实战问题备忘
问题一:怎么把文档标题放在中间呢? 下面这个能解决问题. 居中: <center>诶嘿</center> 左对齐: <p align="left"&g ...
- 过程 sp_addextendedproperty, 对象无效。不允许有扩展属性,或对象不存在。
过程 sp_addextendedproperty, 对象无效.不允许有扩展属性,或对象不存在. 首先这个是创建数据表的SQL,有Power Designer创建模型,直接生成的创建SQL会出现的问题 ...
- SpringBoot整合Netty并使用Protobuf进行数据传输(附工程)
前言 本篇文章主要介绍的是SpringBoot整合Netty以及使用Protobuf进行数据传输的相关内容.Protobuf会简单的介绍下用法,至于Netty在之前的文章中已经简单的介绍过了,这里就不 ...
- 学习ASP.NET Core Razor 编程系列十五——文件上传功能(三)
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...