程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> ASP.NET MVC :MVC頁面驗證與授權

ASP.NET MVC :MVC頁面驗證與授權

編輯:關於ASP.NET

在ASP.NET MVC中,如何來實現表單的驗證與授權訪問呢?至少在CTP3中,還沒有一個官方的解決方案。ASP.NET WebForm的表單驗證和授權 機制是否適合在ASP.NET MVC中使用呢?帶著這些問題來進入我們今天的主題。

在ASP.NET WebForm的架構下,我們可以通過一定的配置 即可實現用戶身份驗證和授權。特別是在ASP.NET 2.0的Membership功能的支撐下,可以做到更加簡潔可復用的用戶驗證系統。通過web.config 可以做到對頁面或目錄對不同用戶身份可見性的定制,但是它是基於物理文件和目錄。而在ASP.NET MVC架構下,用戶訪問的每一個頁面在磁盤 中並沒有一個固定的物理文件,它是通過Controller控制數據與視圖的組合來生成HTML代碼,進而向客戶端輸出。那麼我們該如何來復用已有 的表單驗證授權機制呢?

在MVC中,請求的功能入口是Controller相應的Action函數,我們可以在函數執行前去控制請求權限。在 ASP.NET MVC Preview 2後,提供了一個機制讓我們可以對Action的AOP攔截,這個接口定義如下:

1: public interface IActionFilter

2: {

3: void OnActionExecuted(ActionExecutedContext filterContext);

4: void OnActionExecuting(ActionExecutingContext filterContext);

5: void OnResultExecuted(ResultExecutedContext filterContext);

6: void OnResultExecuting(ResultExecutingContext filterContext);

7: }

我們有兩種方式來實現 攔截,一種我們可以通過定義Attribute來實現攔截的功能,在System.Web.Mvc程序集中有一個ActionFilterAttribute抽象類,通過重寫這個 抽象類的這些虛方法,我們就可以實現對特定的執行過程進行攔截。

另一種方法,我們注意到Controller這個類也實現了 IActionFilter這個接口,並且也提供了這四個函數的虛擬方法定義。框架內部,在調用Action方法的時候同時來調用這些攔截方法。具體的可 以參考:ControllerActionInvoker 這個類的實現,所有的Action的調用都在這個類當中被實現。所以我們只要重寫Controller裡這四個虛方 法,也可完成本Controller面的所有Action的攔截。

在這裡,我也找到了國外友人已經實現好的基於角色的MVC權限控制的方案。自定 義了兩個自定義Attribute,分別為:RequiresAuthenticationAttribute和RequiresRoleAttribute。通過這兩個Attribute來可以作用於Class 和Method,用標記哪些Controller或Action需要登錄後,或者需要擁有哪些角色才能執行。如果用戶沒有擁有訪問當然Controller或Action權 限的時候,就會自動被重定向到登錄頁面去。下面是兩個類的定義:

/// <summary>
/// Checks the User's authentication using FormsAuthentication
/// and redirects to the Login Url for the application on fail
/// </summary>
[RequiresAuthentication]
public class RequiresAuthenticationAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext 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);
}
}
}
/// <summary>
/// Checks the User's role using FormsAuthentication
/// and throws and UnauthorizedAccessException if not authorized
/// </summary>
public class RequiresRoleAttribute : ActionFilterAttribute
{
public string RoleToCheckFor { get; set; }
public override void OnActionExecuting (ActionExecutingContext 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");
}
}
}

如上所介紹的兩種方法,我們一 樣可以定義一個Controller基類,通過攔截來進行權限的控制。但是與定義Attribute相比,手法並不是很好,也不利於通用化。但是就理論上 的性能來說,會比Attribute更好。

到目前為止,ASP.NET MVC還沒有更新的消息,我想在正式版本的ASP.NET MVC框架,權限控制問題 會有一個官方說法。希望到時候會有一種更為靈活和可配置的方案。也許通過控制Url來控制訪問權限也是一種可行的方案,會不會集成到 RouteTable裡面呢?讓我們試目以待吧。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved