【翻譯】ASP.NET MVC : 構建安全的控制器Action

來源:互聯網
上載者:User

原文地址:ASP.NET MVC: Securing Your Controller Actions
原文作者:Rob Conery

本文地址:http://www.cnblogs.com/QLeelulu/archive/2008/04/04/1137580.html
譯者:QLeelulu

首先,希望大家以後關於ASP.NET MVC的文章的Tag統一使用:aspnetmvc (之前我也一直是使用"ASP.NET MVC"的,呵)


The ActionFilterAttribute

ASP.NET MVC Preview 2 引入了新的ActionFilterAttribute,這使你可以在控制器中為你的Action聲明"Filter Attributes"。想一下這個,實質上,就好像"OnLoad"事件—— 一小段代碼在你的Action之前或者之後執行。

使用ActionFilterAttribute 是非常簡單的。你聲明一個類然後重寫基類的一個或者兩個方法:

在這裡你可以看到我們有兩個方法可以重寫:

  • OnActionExecuting: 在調用Action方法前執行(例如可以做為身分識別驗證)
  • OnActionExecuted: 在調用Action方法後執行(例如日誌記錄)

當你建立你的Filter,你此外也可能得訪問FilterExecutingContext -一個非常漂亮的對象,它會告訴你當前的app會發生些什麼:

就算你不是很熟悉Attributes,你也可以聲明屬性,當你使用Attribute你可以為改屬性設值:

你可以好像這樣設定屬性的值:

這將"MyFilterProperty"設定為"SomeSetting",你可以在你的OnActionExcuting方法中使用這個屬性。

Putting It Together
我們想要做的是在調用Action之前先檢查當前的使用者是否已經登入,如果沒有登入我們就將他重新導向到登入頁,並追加一個讓他可以返回的當前頁的URL。

為什麼使用一個Filter而不是好像Webforms一樣使用Web.config ?原因是你不可以準確的鎖定一個Action來使用Forms認證,在之前,Phil 討論了這個並做了很好的解釋:

====>>>>>>
假如你有一個website,而你想阻止未經驗證的使用者訪問Admin檔案夾。做為一個標準的網站,一個途徑是可以將下面的Web.config檔案放到Admin檔案夾...中:

<?xml version="1.0"?><configuration>    <system.web>                <authorization>            <deny users="*" />        </authorization>    </system.web></configuration>

嘗試導航到Admin目錄下你會得到一個拒絕訪問的錯誤。然而,你可能會好像下面一樣使用一個實現了WebFormRouteHandler 的連結將URL fizzbucket映射到Admin目錄下:

RouteTable.Routes.Add(new Route("fizzbucket", new WebFormRouteHandler("~/admin/secretpage.aspx"));

現在,一個請求 /fizzbucket 的URL將會顯示Admin目錄下的 secretpage.aspx。這可能是你一直想要的。不過,這可能並不能達到你想要的效果。(原文:Now, a request for the URL /fizzbucket will display secretpage.aspx in the admin directory. This might be what you want all along. Then again, it might not be.)
<<<<<<====

這裡的要點是Urls不是映射到Pages和目錄 而且 有不止一種途徑來Skin An Action(不知道怎麼翻譯,skim?) ——你可以容易地在底層用你的routes來映射,而且會不經意的開啟一個連結到受安全保護的頁面的URL(原文:you can easily shoot yourself in the foot with your routes, and inadvertantly open up a Url to a secured page)。構建安全的Action始終是更好的選擇。

指出所有的這些,我們現在可以開始構建我們新的Filter來檢查身分識別驗證了-the RequiresAuthentication Filter:

   /// <summary>   /// 使用FormsAuthentication來檢查使用者的身分識別驗證   /// 並在驗證失敗時重新導向到登入頁   /// </summary>   public class RequiresAuthenticationAttribute : ActionFilterAttribute {        public override void OnActionExecuting(FilterExecutingContext filterContext) {                       //redirect if not authenticated            if (!filterContext.HttpContext.User.Identity.IsAuthenticated) {                                //use the current url for the redirect                string redirectOnSuccess = filterContext.HttpContext.Request.Url.AbsolutePath;                //send them off to the login page                string redirectUrl = string.Format("?ReturnUrl={0}", redirectOnSuccess);                string loginUrl = FormsAuthentication.LoginUrl + redirectUrl;                filterContext.HttpContext.Response.Redirect(loginUrl, true);            }        }    }

使用這個是非常的簡單的——只需將它附加到你想要受安全保護的Action方法中就可以了:

另外一個很有用的Filter是用來檢查特定的角色:

/// <summary>/// 使用FormsAuthentication來檢查使用者的角色/// 如果未授權的時候會拋出一個 UnauthorizedAccessException 異常/// </summary>public class RequiresRoleAttribute : ActionFilterAttribute {                public string RoleToCheckFor { get; set; }        public override void OnActionExecuting(FilterExecutingContext filterContext) {            //redirect if the user is not authenticated            if (!String.IsNullOrEmpty(RoleToCheckFor)) {                                if (!filterContext.HttpContext.User.Identity.IsAuthenticated) {                    //use the current url for the redirect                    string redirectOnSuccess = filterContext.HttpContext.Request.Url.AbsolutePath;                    //send them off to the login page                    string redirectUrl = string.Format("?ReturnUrl={0}", redirectOnSuccess);                    string loginUrl = FormsAuthentication.LoginUrl + redirectUrl;                    filterContext.HttpContext.Response.Redirect(loginUrl, true);                } else {                    bool isAuthorized = filterContext.HttpContext.User.IsInRole(this.RoleToCheckFor);                    if (!isAuthorized)                        throw new UnauthorizedAccessException("You are not authorized to view this page");                }            } else {                throw new InvalidOperationException("No Role Specified");            }        }    }

注意我在這裡傳了一個字串用來檢查角色:

你可以修改這個為一個枚舉、常量、或者其他的。你也可以將他修改為具有更多的行為——例如 "RequiresUserCanEditPage" 並在這個方法中確保使用者為 "Administrators"或者 "Content Editors".這裡的point是由你決定的。

 

PS:汗一個,英文好菜,好幾個地方不知道怎麼翻譯。Orz....

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.