如何在MVC 5中将角色与用户相关联?

时间:2019-04-10 13:45:49

标签: c# asp.net-mvc-5 asp.net-roles

在WebForms上,我曾经将角色存储在FormsAuthenticationTicket用户数据中,但是我尝试在mvc 5中实现相同的方法,但该方法不起作用。由于某些原因

User.Identity.IsAuthenticated

这将返回false

var ticket = new FormsAuthenticationTicket(
    1,
    user.Id.ToString(),
    DateTime.Now,
    DateTime.Now.AddDays(5),
    model.RememberMe,
    user.Roles.Select(c => c.Nome).FirstOrDefault(),
    FormsAuthentication.FormsCookiePath
);

// Encrypt the ticket.
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
// Create the cookie.
HttpCookie authenticationCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); // Name of auth cookie (it's the name specified in web.config) // Hashed ticket
authenticationCookie.Expires = DateTime.Now.AddDays(7);
// Add the cookie to the list for outbound response
Response.Cookies.Add(authenticationCookie);

所以因为这行不通,所以我改用

FormsAuthentication.SetAuthCookie(user.Id.ToString(), model.RememberMe);

这个问题是,它不允许我轻松访问用户角色,以便我可以在视图上进行操作

if (User.IsInRole("Admin"))

我要避免使用Asp Net Identity,因为它需要大量的自定义,并且我不需要所有其他字段或密码,因为我们需要通过ldap进行身份验证。

如果还有其他选择,请告知我。

1 个答案:

答案 0 :(得分:0)

表单身份验证本身不支持角色。因此,您需要使用角色manually设置请求的IPrincipal。您可以通过“订阅” Global.asax中的验证后事件来完成此操作,并更新记录的用户信息。在MvcApplication的{​​{1}}类内添加以下方法

Global.asax.cs

此外,您需要更新登录代码以创建正确的protected void Application_OnPostAuthenticateRequest(object sender, EventArgs e) { HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName]; if (authCookie != null) { //get the forms authentication ticket FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value); string userData = authTicket.UserData; //here we suppose userData contains roles joined with "," string[] roles = userData.Split(','); //at this point we already have Context.User set by forms authentication module //we don't change it but add roles var principal = new GenericPrincipal(Context.User.Identity, roles); // set new principal with roles Context.User = principal; } } ,其中包含以“,”开头的角色

FormsAuthenticationTicket

另一种选择是通过在var roles = user.Roles.Select(c => c.Nome); var ticket = new FormsAuthenticationTicket( 1, user.Id.ToString(), DateTime.Now, DateTime.Now.AddDays(5), model.RememberMe, string.Join(",", roles), //or you can serialize complex class as json or whatever FormsAuthentication.FormsCookiePath ); 中添加FormsAuthentication_OnAuthenticate方法来override forms authentication

Global.asax.cs

两种解决方案都非常相似,因此您可以选择一种解决方案。