ASP.NET MVC 2 Authorize - 自定义Authorize的实现
本文主要是轉載的,通過這個小例子可以輕松自定義你的Authorize權限控制,因為我不是特別了解ASP.NET WebForm的MemberShip的實現(xiàn)機制,也不敢說自定義的性能是否過關,目前使用自定義的比較順手。
在ASP.NET MVC2中使用自定義的AuthorizeAttribute繞過內置的Membership/Role機制
感謝 DSO at http://stackoverflow.com/users/38087/DSO
在ASP.NET MVC2中,我們可以使用Authorize Filter限制用戶對內容的訪問,如
- [Authorize]
- public class MyController : Controller
- {
- // ...
- }
- // 或者
- [Authorize(Roles="Admin")]
- public class MyController : Controller
- {
- // ...
- }
但前提是要用到Membership / Role機制。 我們要不就使用內置的機制,要不就派生出自己的。
不管怎樣,都比較麻煩,其實我們可以繞過這套機制,而且還能使用AuthorizeAttribute。
以下是DSO的看法:
With MVC it is simple to bypass the Membership and Role provider framework altogether. Sometimes it is easier to do this than to implement custom Membership/Role providers, in particular if your authn/authz model doesn't quite fit the mold of those providers.
First, you should realize that you don't need to write everything from scratch, you can use the core Forms authentication API, which can be used independently of the Membership/Role provider framework:
- FormsAuthentication.SetAuthCookie- Call this after user has been authenticated, specify the user name
- Request.IsAuthenticated- Returns true if SetAuthCookie was called
- HttpContext.Current.User.Identity.Name- Returns the user name specified in the call to SetAuthCookie
So here is what you do in MVC to bypass the Membership/Role provider:
Authentication : In your controller, authenticate the user using your custom logic.If successful, callFormsAuthentication.SetAuthCookiewith the user name.
Authorization : Create a custom authorize attribute (deriving from AuthorizeAttribute) . In theAuthorizeCoreoverride, implement your custom authorization logic, taking the user inHttpContext.Current.User.Identity.Nameand the roles defined in the Roles property of the AuthorizeAttribute base class. Note you can also define properties on your custom authorization attribute and use that in your authorization logic. For example you can define a property representing roles as enumerated values specific to your app, instead of using the Roles property which is just a string.
Affix your controllers and actions with your custom authorize attribute, instead of the default Authorize attribute.
我看了感覺很受啟發(fā),但卻不太清楚如何重載AuthorizeAttribute的AuthorizeCore方法。為此我做了個Demo:
1. 使用VS2010建立一個ASP.NET MVC2 Web工程Aut,在Model目錄下新建一個MyAuthAttribute類,如下:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
- namespace AuthTest.Models
- {
- public class MyAuthAttribute : AuthorizeAttribute
- {
- // 只需重載此方法,模擬自定義的角色授權機制
- protected override bool AuthorizeCore(HttpContextBase httpContext)
- {
- string currentRole = GetRole(httpContext.User.Identity.Name);
- if(Roles.Contains(currentRole ) )
- return true;
- return base.AuthorizeCore(httpContext);
- }
- // 返回用戶對應的角色, 在實際中, 可以從SQL數(shù)據(jù)庫中讀取用戶的角色信息
- private string GetRole(string name)
- {
- switch(name)
- {
- case "aaa": return "User";
- case "bbb": return "Admin";
- case "ccc": return "God";
- default: return "Fool";
- }
- }
- }
- }
2. 修改HomeController, 如下
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
- using System.Web.Security;
- using AuthTest.Models;
- namespace AuthTest.Controllers
- {
- [HandleError]
- public class HomeController : Controller
- {
- public ActionResult Index()
- {
- ViewData["Message"] = "歡迎使用 ASP.NET MVC!";
- // 模擬用戶成功登錄
- FormsAuthentication.SetAuthCookie("aaa", false);
- return View();
- }
- // 驗證我們自定義的AuthorizeAttribute是否起作用,
- // 此Action只能由角色為“God”的用戶訪問
- [MyAuth(Roles="God")]
- public ActionResult About()
- {
- return View();
- }
- }
- }
3. 按F5調試,再點擊頁面上的“關于”鏈接,哈哈,知道了吧?