asp.net framework下webform、webapi和mvc对于文件增加权限校验
webform
新建WebForm
新建Global.asax
using System;
using System.Web.Routing;namespace FileAuthStu01
{public class Global : System.Web.HttpApplication{protected void Application_Start(object sender, EventArgs e){RouteTable.Routes.RouteExistingFiles = true;//如果没有处理则默认还是会走静态文件返回,IgnoreRoute是MVC才有的//RouteTable.Routes.IgnoreRoute("Content/{*relpath}");RouteTable.Routes.MapPageRoute("ImageRoute","image/imgs/{imageName}","~/ImageHandler.aspx",true,new RouteValueDictionary { { "imageName", "" } });}}
}
修改web.config
<system.webServer><!-- 确保所有请求都经过ASP.NET的管道处理 --><modules runAllManagedModulesForAllRequests="true" /><handlers></handlers><!--设置默认起始页面--><defaultDocument><files><clear /><add value="index.aspx" /></files></defaultDocument>
</system.webServer>
新建ImageHandler.aspx
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Web;namespace FileAuthStu01
{public partial class ImageHandler : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){//TODO 验证是否有权限,按照逻辑自己实现//方法1 获取jwt等授权信息判断是否有权限查看,适合点击下载事件一般用于POST请求//var authData = Request.Headers.Get("Authorization");//方法2 将缓存的参数通过query参数写入,实现显示一次就将缓存取消阅后即焚的效果//也可以增加一些参数,比如设置图片大小等参数,一般用于GET请求string imageName = RouteData.Values["imageName"] as string;if (string.IsNullOrEmpty(imageName)){//文件不存在Response.StatusCode = 404;return;}var imagePath = Server.MapPath($"~/image/imgs/{imageName}");if (!File.Exists(imagePath)){//文件不存在Response.StatusCode = 404;return;}var fileStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);//清除缓存Response.Clear();Response.ClearHeaders();Response.ClearContent();BinaryReader br = new BinaryReader(fileStream);var speed = 1024 * 10;//10kb每秒的速度下载或者预览,下载速度限制1024 kb/s,Mb/s就是1024*1024bool isDownload = false;//是否是直接下载还是预览try{Response.AddHeader("Accept-Ranges", "bytes");Response.Buffer = false;long fileLength = fileStream.Length;long startBytes = 0;Response.AddHeader("Content-Length", (fileLength - startBytes).ToString());if (startBytes != 0){Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength));}Response.AddHeader("Connection", "Keep-Alive");if (isDownload){//下载时用它Response.ContentType = "application/octet-stream";Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(imageName, System.Text.Encoding.UTF8));}else{//预览时可以用它浏览器能识别才可以,比如图片string mimeType = MimeMapping.GetMimeMapping(imagePath);Response.ContentType = mimeType;}byte[] buff = new byte[speed];var contentLength = br.Read(buff, 0, speed);double d = 1000; // 限速时每个包的时间,现在是1秒Stopwatch wa = new Stopwatch();while (contentLength != 0){if (Response.IsClientConnected){wa.Restart();Response.BinaryWrite(buff);Response.Flush();contentLength = br.Read(buff, 0, speed);wa.Stop();if (wa.ElapsedMilliseconds < d) //如果实际带宽小于限制时间就不需要等待{Thread.Sleep((int)(d - wa.ElapsedMilliseconds));}}else{break;}}}catch (Exception ex){Response.Write(ex.ToString());}finally{br.Close();fileStream.Close();}}}
}
访问002就会提示404
webapi
新建WebApiConfig.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.Routing;
using System.Web.Security;namespace FileAuthStu03
{public static class WebApiConfig{public static void Register(HttpConfiguration config){// Web API 配置和服务RouteTable.Routes.RouteExistingFiles = true;// Web API 路由config.MapHttpAttributeRoutes();config.Routes.MapHttpRoute("StaticFile","image/imgs/{*fileName}",defaults: new { controller = "StaticFile", action = "Index" });config.Routes.MapHttpRoute(name: "DefaultApi",routeTemplate: "api/{controller}/{id}",defaults: new { id = RouteParameter.Optional });}}
}
Global.asax
protected void Application_Start()
{GlobalConfiguration.Configure(WebApiConfig.Register);
}
修改web.config
<system.webServer><!-- 确保所有请求都经过ASP.NET的管道处理 --><modules runAllManagedModulesForAllRequests="true" /><handlers><remove name="ExtensionlessUrlHandler-Integrated-4.0" /><remove name="OPTIONSVerbHandler" /><remove name="TRACEVerbHandler" /><add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /></handlers>
</system.webServer>
新建FileReusltContent.cs
using System.IO;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Net;
using System.Threading.Tasks;
using System.Threading;
using System.Web.Http;namespace FileAuthStu03.Controllers
{public class FileReusltContent : IHttpActionResult{private readonly string _filePath;private readonly string _contentType;private readonly string _fileDownloadName;public FileReusltContent(string filePath, string contentType, string fileDownloadName){_filePath = filePath;_contentType = contentType;_fileDownloadName = fileDownloadName;}public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken){var response = new HttpResponseMessage(HttpStatusCode.OK);var stream = new FileStream(_filePath, FileMode.Open, FileAccess.Read);response.Content = new StreamContent(stream);response.Content.Headers.ContentType = new MediaTypeHeaderValue(_contentType);if (!string.IsNullOrEmpty(_fileDownloadName)){response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"){FileName = _fileDownloadName};}return Task.FromResult(response);}}
}
新建StaticFileController.cs
using System.Web;
using System.Web.Http;namespace FileAuthStu03.Controllers
{public class StaticFileController : ApiController{/// <summary>/// 根据权限返回图片/// </summary>/// <param name="fileName"></param>/// <returns></returns>[HttpGet]public IHttpActionResult Index(string fileName){var filePath = HttpContext.Current.Server.MapPath(fileName);if (!System.IO.File.Exists(filePath)){return NotFound();}//TODO 实现权限校验逻辑string mimeType = MimeMapping.GetMimeMapping(fileName);return new FileReusltContent(filePath, mimeType, string.Empty);}}
}
mvc
修改RouteConfig.cs
using System.Web.Mvc;
using System.Web.Routing;namespace FileAuthStu02
{public class RouteConfig{public static void RegisterRoutes(RouteCollection routes){routes.RouteExistingFiles = true;//忽略某些路由routes.IgnoreRoute("{resource}.axd/{*pathInfo}");//mvc比较特殊需要设置忽略路由要不然访问会出现404routes.IgnoreRoute("Content/{*relpath}");routes.IgnoreRoute("Scripts/{*relpath}");routes.MapRoute(name: "StaticFile",url: "image/imgs/{*fileName}",defaults: new { controller = "StaticFile", action = "Index"});routes.MapRoute(name: "Default",url: "{controller}/{action}/{id}",defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });}}
}
新建StaticFileController.cs
using System.IO;
using System.Web;
using System.Web.Mvc;namespace FileAuthStu02.Controllers
{public class StaticFileController : Controller{/// <summary>/// 根据权限返回图片/// </summary>/// <param name="fileName"></param>/// <returns></returns>[HttpGet]public ActionResult Index(string fileName){var filePath = Server.MapPath(fileName);if (!System.IO.File.Exists(filePath)) {return View();}//TODO 实现权限校验逻辑var fileStream = new FileStream(filePath, FileMode.Open);string mimeType = MimeMapping.GetMimeMapping(fileName);return new FileStreamResult(fileStream, mimeType);}}
}
修改web.config
<system.webServer><!-- 确保所有请求都经过ASP.NET的管道处理 --><modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
运行效果同上如果有其他的操作可以在代码里面编写
参考
https://blog.csdn.net/WuLex/article/details/68600672
https://www.cnblogs.com/liujie2272/p/13047703.html
https://blog.csdn.net/weixin_30432007/article/details/94833705
https://blog.csdn.net/zp19860529/article/details/106282592
限制下载速度
https://blog.csdn.net/weixin_34144450/article/details/94245905
https://www.cnblogs.com/zzl-1987/p/4462695.html
https://www.cnblogs.com/Music/archive/2012/07/28/asp-net-limit-download-speed.html
https://www.cnblogs.com/coredx/p/17195492.html#qq%E7%BE%A4
https://blog.51cto.com/u_15076218/4145892