ASP.NET MVC Filter練習-限定本機存取

在ASP.NET MVC專案新增了開發偵錯專用的Controller,某些Action想限定從localhost存取,以免遭到誤用。逐一在Action加入檢查IP邏輯是種做法,但如此有點浪費ASP.NET MVC強大的擴充性,就好比提著子彈上膛的M16步槍上戰場,不扣板機卻拿槍托狂敲敵人的頭,不免有暴殄天物之憾。

ASP.NET MVC有個Filter機制(中文翻成篩選器),在Filter可自訂執行Action時要一併觸發的邏輯,為Action加上[FilterName] Attribute,便可在該Action之前或之後插入自訂邏輯。這種概念很適合用來實現Log記錄、權限控管、Exception處理... 等等通用性任務。而IAuthorizationFilter介面專司權限管控,符合IP篩選的安全性質,因此我的構想是寫個類別,實做IAuthorizationFilter介面的OnAuthorization()方法,由傳入的AuthorizationContext取得UserHostAddress判斷來源IP,若HttpRequest不是來自本機(localhost)即拋出錯誤,就實現了Action只開放本機存取的效果。

FilterAttribute完成後,任何Action只要加上該FilterAttribute宣告,就會自動套用上述檢查限定本機存取,非常簡便易用。

以下是完整程式範例,為了增加應用彈性,我特別再抽出一層AllowedIpOnlyAttribute,宣告時傳入允許存取的IP清單;而LocalhostOnlyAttribute繼承AllowedIpOnlyAttribute,將允許IP寫死::1(IPv6)及127.0.0.1,成為AllowedIpOnlyAttribute的特例,做到限定本機存取。如此一魚兩吃,一次獲得兩種Filter,適用於不同情境。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
 
namespace MyWeb.Models
{
    public class AllowedIpOnlyAttribute : FilterAttribute, IAuthorizationFilter
    {
        private string[] ipList = new string[] {};
        //建構式接收以逗號或分號分隔的IP清單,限定存取來源
        //TODO: 如要方便事後修改,可擴充成由config讀取IP清單,但會增加被破解風險
        public AllowedIpOnlyAttribute(string allowedIps)
        {
            ipList = allowedIps.Split(',', ';');
        }
        #region IAuthorizationFilter Members
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            //實作OnAuthorization,當來源IP不在清單上,彈出錯誤
            string clientIp = filterContext.HttpContext.Request.UserHostAddress;
            if (!ipList.Contains(clientIp))
                throw new ApplicationException("Disallowed Client IP!");
        }
        #endregion
    }
    //限定本機存取為AllowedIpOnlyAttribute的特殊情境,限定IP=::1或127.0.0.1
    public class LocalhostOnlyAttribute : AllowedIpOnlyAttribute
    {
        public LocalhostOnlyAttribute()
            : base("::1;127.0.0.1")
        {
        }
    }
}

接著,見識Filter便利性的時刻來了,在Action加上AllowedIpOnly或LocalhostOnly,Action立刻變成限定特定IP或本機IP才能使用! 很方便吧?

        [AllowedIpOnly("192.168.1.100")]
        public ActionResult IpOnly()
        {
            return Content("IpOnly");
        }
        [LocalhostOnly]
        public ActionResult LocalhostOnly()
        {
            return Content("LocalHostOnly");
        }
歡迎推文分享:
Published 15 September 2013 05:08 PM 由 Jeffrey
Filed under: ,
Views: 8,645



意見

沒有意見

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<September 2013>
SunMonTueWedThuFriSat
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication