用Filter实现图片防盗链

本文介绍如何在ASP.NET MVC中实现防盗链功能,通过自定义Filter来限制文件和图片的访问来源,防止被非法盗链。包括具体代码实现、控制器应用以及测试结果分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先继承自FilterAttribute类同时实现IActionFilter接口,代码如下:

//// <summary>
/// 防盗链Filter.
/// </summary>
public class AntiOutSiteLinkAttribute : ActionFilterAttribute, IActionFilter
{
    public AntiOutSiteLinkAttribute(FileType fileType)
    {
        this.FileType = fileType;
    }

    //// <summary>
    /// 请求的文件类型.(文件或图片)
    /// </summary>
    public FileType FileType { get; set; }

    #region IActionFilter 成员

    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpContextBase httpContext = filterContext.HttpContext;
        if (null != httpContext.Request.UrlReferrer)
        {
            string serverDomain = httpContext.Request.Url.Host;
            string refDomain = httpContext.Request.UrlReferrer.Host;
            if (GetRootDomain(refDomain).Equals(GetRootDomain(serverDomain), StringComparison.OrdinalIgnoreCase))
            {
                return;//如果根域名相同就返回
            }
        }

        ContentResult cr = new ContentResult();
        if (FileType == FileType.Image)
        {
            cr.ContentType = "image/jpeg";
            FileInfo fi = new FileInfo(httpContext.Server.MapPath("~/Content/images/outsitelink.jpg"));
            if (fi.Exists)
            {
                httpContext.Response.WriteFile(fi.FullName);
            }
            else
            {
                Bitmap bmp = new Bitmap(200, 50);
                Graphics g = Graphics.FromImage(bmp);
                g.FillRectangle(Brushes.White, 0, 0, 200, 50);
                g.DrawString("请不要盗链", new Font("Arial", 15), Brushes.Red, new PointF(0, 0));
                bmp.Save(httpContext.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);
            }
        }
        else
        {
            cr.ContentType = "text/html";
            cr.Content = string.Format("请不要盗链。返回<a href='{0}'>{1}</a>", Utils.AbsoluteWebRoot, BlogSettings.Instance.Name);
        }
        //将当前的上下文的ActionResult设置为我们的cr(ContentResult)
        filterContext.Result = cr;
    }
    #endregion

    //// <summary>
    /// 获取网站的根域名
    /// </summary>
    /// <param name="domain">网站的域名,不带"Http://"</param>
    /// <returns></returns>
    private string GetRootDomain(string domain)
    {
        if (string.IsNullOrEmpty(domain))
        {
            throw new ArgumentNullException("参数'domain'不能为空");
        }
        string[] arr = domain.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
        if (arr.Length <= 2)
        {
            return domain;
        }
        else
        {
            return arr[arr.Length - 2] + "." + arr[arr.Length - 1];
        }
    }
}

public enum FileType
{
    File = 1,
    Image
}

然后我们建立一个用于处理文件请求的Controller,并应用上我们刚才建立的Filter:

public class FilesController : BaseController
 {
     [AntiOutSiteLink(FileType.Image)]
     public ActionResult Image(string file)
     {
         return Content("Image From 4mvc");
     } 

     [AntiOutSiteLink(FileType.File)]
     public ActionResult File(string file)
     {
         return Content("File From 4mvc");
     }
 } 

测试结果:

image

 

对于ActionFilter的应用是很广泛的,需要灵活运用。对于其他应用,可以参考ASP.NET MVC Action Filter - 缓存与压缩 这一篇文章。

 

转载于:https://www.cnblogs.com/sky-net/p/4396150.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值