我正在升级网站以使用MVC,我正在寻找设置身份验证的最佳方式。
此时,我已登录Active Directory:验证用户名和密码,然后设置Auth cookie。
如何在登录时存储用户的角色信息,以便我的控制器在用户浏览网站时查看这些角色?
[Authorize(Roles = "admin")]
从Active Directory获取角色列表没有问题。我只是不知道把它们放在哪里,以便控制器能够看到它们。
答案 0 :(得分:124)
将角色添加到HttpContext的IPrincipal。您可以创建GenericPrincipal,解析构造函数中的角色列表并将其设置为HttpContext.User。然后,可以通过User.IsInRole("role")
或[Authorize(Roles="role")]
属性
执行此操作的一种方法(在C#中)是在创建身份验证票证时将您的角色添加为用户数据参数中的逗号分隔字符串
string roles = "Admin,Member";
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
1,
userId, //user id
DateTime.Now,
DateTime.Now.AddMinutes(20), // expiry
false, //do not remember
roles,
"/");
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,
FormsAuthentication.Encrypt(authTicket));
Response.Cookies.Add(cookie);
然后从身份验证票证访问角色列表并从Global.asax.cs创建GenericPrincipal
protected void Application_AuthenticateRequest(Object sender, EventArgs e) {
HttpCookie authCookie =
Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null) {
FormsAuthenticationTicket authTicket =
FormsAuthentication.Decrypt(authCookie.Value);
string[] roles = authTicket.UserData.Split(new Char[] { ',' });
GenericPrincipal userPrincipal =
new GenericPrincipal(new GenericIdentity(authTicket.Name),roles);
Context.User = userPrincipal;
}
}
答案 1 :(得分:6)
对用户进行身份验证时,会生成一个新的GenericPrincipal实例。构造函数接受一个字符串数组,这些字符串是用户的角色。现在将HttpContext.Current.User设置为等于泛型主体并编写auth cookie,并且应该这样做。
答案 2 :(得分:4)
对于那些使用MVC 4或更高版本的人,在使用David Glenn的答案时,您需要采用Jaroslaw Waliszko的建议:
“我在ASP.NET MVC 4中对它进行了测试,我建议使用Application_PostAuthenticateRequest。否则将覆盖通用主体。” - Jaroslaw Waliszko 9月7日16:18
如上所述,您需要做的就是将Application_AuthenticateRequest方法名称替换为Application_PostAuthenticateRequest以使其生效。对我来说就像一个魅力!如果我被允许赞成Jaroslaw和David,我会的。
答案 3 :(得分:3)
我倾向于创建自定义角色提供程序。示例:
答案 4 :(得分:1)
您是否可以放入使用Active Directory的authorization store role manager或find (e.g. on Codeplex)或write其他角色提供程序来获取群组信息?
这样可以省去验证用户,获取角色,然后将这些信息重新传递给构造函数的麻烦,并且这些都会自动作为框架的一部分自动发生。