我会将这些信息存储在认证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