首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

ASP.NET MVC Action Filter 實戰:防盜連結完整實作(繼承 ActionFilterAttribute 實作 IActionFilter)

     編輯:關於ASP.NET

前言

承接前文 Action Filter 介紹,本文實作一個防盜連結 Filter,攔截非本站域名的圖片/檔案請求,回傳警告圖片或訊息。

完整程式碼

public class AntiOutSiteLinkAttribute : ActionFilterAttribute, IActionFilter
{
    public AntiOutSiteLinkAttribute(FileType fileType)
    {
        this.FileType = fileType;
    }

    public FileType FileType { get; set; }

    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpContextBase httpContext = filterContext.HttpContext;
        if (httpContext.Request.UrlReferrer != null)
        {
            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);
        }
        filterContext.Result = cr; // 短路管線,直接回傳結果
    }

    private string GetRootDomain(string domain)
    {
        if (string.IsNullOrEmpty(domain))
            throw new ArgumentNullException("domain");
        string[] arr = domain.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
        return (arr.Length <= 2) ? domain : arr[arr.Length - 2] + "." + arr[arr.Length - 1];
    }
}

public enum FileType { File = 1, Image }

核心邏輯解析

  1. 判斷 Referrer:取得 Request.UrlReferrer.Host,若為空(直接輸入網址)視為盜連。
  2. 根域名比對:擷取根域名(如 example.com),忽略子域名差異。
  3. 區分檔案類型:FileType.Image 回傳圖片;其他回傳 HTML 連結。
  4. 動態產生警告圖:若無預設警告圖,使用 GDI+ 即時繪製。
  5. 短路管線:設定 filterContext.Result,阻止後續 Action 執行。

套用方式

[AntiOutSiteLink(FileType.Image)]
public ActionResult ShowImage(string id) { ... }

結語

Action Filter 讓橫切關注點(如防盜連、權限、快取)以聲明式方式套用,程式碼集中、可重用、易維護。此範例展示完整攔截與回應邏輯,可直接套用於專案中。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved