我會將這些信息存儲在認證cookie的用戶數據部分。因此,當用戶登錄:
public ActionResult Login(string username, string password)
{
// TODO: validate username/password couple and
// if they are valid get the roles for the user
var roles = "RoleA|RoleC";
var ticket = new FormsAuthenticationTicket(
1,
username,
DateTime.Now,
DateTime.Now.AddMilliseconds(FormsAuthentication.Timeout.TotalMilliseconds),
false,
roles
);
var encryptedTicket = FormsAuthentication.Encrypt(ticket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
{
// IIRC this property is only available in .NET 4.0,
// so you might need a constant here to match the domain property
// in the <forms> tag of the web.config
Domain = FormsAuthentication.CookieDomain,
HttpOnly = true,
Secure = FormsAuthentication.RequireSSL,
};
Response.AppendCookie(authCookie);
return RedirectToAction("SomeSecureAction");
}
然後我會寫一個會照顧讀取和解析的身份驗證票證和存儲的HttpContext一個通用的用戶自定義屬性authroize。用戶屬性與它對應的角色:
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext.User.Identity.IsAuthenticated)
{
var authCookie = httpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
var ticket = FormsAuthentication.Decrypt(authCookie.Value);
var roles = ticket.UserData.Split('|');
var identity = new GenericIdentity(ticket.Name);
httpContext.User = new GenericPrincipal(identity, roles);
}
}
return base.AuthorizeCore(httpContext);
}
}
接下來,您可以裝飾你的控制器/與這個屬性的行動來處理權限:
// Only users that have RoleA or RoleB can access this action
// Note that this works only with OR => that's how the base
// authorize attribute is implemented. If you need to handle AND
// you will need to completely short-circuit the base method call
// in your custom authroize attribute and simply handle this
// case manually
[MyAuthorize(Roles = "RoleA,RoleB")]
public ActionResult Foo()
{
...
}
爲了檢查用戶是否只是一個給定的角色:
bool isInRole = User.IsInRole("RoleC");
有了這些信息,您就可以開始思考如何組織您的視圖模型。在這些視圖模型中,我將包含布爾型屬性,如CanEdit
,CanViewReport
,...將由控制器填充。
現在,如果您在每個操作和視圖中都需要此映射,那麼事情可能會變得重複和無聊。這是全局自定義動作過濾器發揮作用的地方(它們並不存在於ASP.NET MVC 2中,只存在於ASP.NET MVC 3中,因此您可能需要使用此動作過濾器進行裝飾的基本控制器,該控制器模擬的差不多相同功能)。您只需定義這樣的全局動作過濾器,它在每個動作之後執行,並將一些常見視圖模型注入ViewData(聖潔....,不能相信我在發音這些單詞),並因此使其可用於所有視圖的橫向其他行動方式。
最後在視圖中,您將檢查這些布爾值屬性以包含或不包含網站的不同區域。就JavaScript代碼而言,如果它不引人注意,那麼如果這些區域不存在於DOM中,那麼這些代碼將不會運行。如果你需要更細粒度的控制,你總是可以在你的DOM元素上使用HTML5 data-*
屬性來給你的外部javascript函數提供關於用戶授權的提示。
無法通過web.config中的基於位置的授權安全設置來控制此功能嗎? – Holystream 2011-03-29 17:58:44