基于声明的表单身份验证角色 [英] Claims Based Forms Authentication Roles

查看:123
本文介绍了基于声明的表单身份验证角色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用MVC 4中的表单身份验证来对用户进行身份验证(我使用的是RavenDB,所以我不能使用标准的成员资格提供程序).然后,稍后我使用User.IsInRole()方法或AuthorizeAttribute来验证用户是否具有职员角色.

I'm trying to authenticate a user using forms authentication in MVC 4 (I'm using RavenDB so I can't use the standard membership providers). Then later I'm using the User.IsInRole() method or AuthorizeAttribute to verify the user is in a staff role.

在这里,我将票证设置为成功通过身份验证(此刻在UserController.cs中):

Here's where I set the ticket on successful authentication (at the moment in UserController.cs):

FormsAuthenticationTicket ticket =
    new FormsAuthenticationTicket(
        1,
        model.Email,
        DateTime.Now,
        DateTime.Now.AddDays(1),
        false,
        model.Email);

string hashedTicket = FormsAuthentication.Encrypt(ticket);

HttpCookie cookie =
    new HttpCookie(
        FormsAuthentication.FormsCookieName,
        hashedTicket);

HttpContext.Response.Cookies.Add(cookie);

在这里,我检查每个请求的票证(Global.asax):

Here's where I check the ticket for each request (Global.asax):

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
    var authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];

    if (authCookie != null)
    {
        var authTicket = FormsAuthentication.Decrypt(authCookie.Value);
        var user = this.UserService.GetUserByEmail(authTicket.Name);

        var identity = new GenericIdentity(authTicket.Name, "Forms");

        var principal = new GenericPrincipal(identity, user.Roles);

        HttpContext.Current.User = principal;
    }
}

如果然后在我的一种操作方法(CalendarController.cs)上放置一个调试点,则得到isStaff等于false:

If I then put a debug point on one of my action methods (CalendarController.cs), I get isStaff equals false:

public ActionResult Index()
{
    var user = HttpContext.User;

    bool isStaff = user.IsInRole(Role.Staff);

    return View();
}

仅仅是为了完成(Roles.cs,只是一个用于测试事物的临时类):

Just for completion (Roles.cs, just a temporary class to test things):

public static class Role
{
    public static string Staff
    {
        get { return "Staff"; }
    }

    public static string Manager
    {
        get { return "Manager"; }
    }
}

任何人都可以帮助我指出我可能会想念的东西吗?看来我设置的角色在我使用动作方法时就消失了.

Can anyone help give me a point as to what I might be missing? It looks as though the roles I set are disappearing by the time I get to the action method.

推荐答案

感谢大家为我提供帮助,我提出的建议(包括以下内容)非常有用!如果用户具有有效的票证(cookie),它将直接通过登录屏幕自动登录,并且还使用ClaimsIdentityClaimsPrincipal对象处理基于声明的角色,而无需将角色放在用户的cookie中.它还可以处理Global.asax.cs文件中的身份验证,而不必借助自定义授权属性.

Thanks guys for helping me with this, what I've come up with (included below) works great! It auto-logs users straight in through the login screen if they have a valid ticket (cookie) and also handles Claims based roles using the ClaimsIdentity and ClaimsPrincipal objects, without putting the roles in the user's cookie. It also handles authentication in the Global.asax.cs file without having to resort to putting in custom authorize attributes.

UserController.cs

public ActionResult Login()
{
    LoginViewModel model = new LoginViewModel();

    if ((HttpContext.User != null) &&
        (HttpContext.User.Identity.IsAuthenticated))
    {
        return RedirectToAction("Index", "Home");
    }

    return View(model);
}

[HttpPost]
public ActionResult Login(LoginViewModel model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    bool isAuthenticated = this.userService.IsPasswordValid(model.Email, model.Password);

    if (!isAuthenticated)
    {
        ModelState.AddModelError("AuthError", Resources.User.Login.AuthError);

        return View(model);
    }

    FormsAuthentication.SetAuthCookie(model.Email, model.RememberUser);

    return RedirectToAction("Index", "Home");
}

Global.asax.cs

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
    var authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];

    if (authCookie != null)
    {
        var ticket = FormsAuthentication.Decrypt(authCookie.Value);

        FormsIdentity formsIdentity = new FormsIdentity(ticket);

        ClaimsIdentity claimsIdentity = new ClaimsIdentity(formsIdentity);

        var user = this.UserService.GetUserByEmail(ticket.Name);

        foreach (var role in user.Roles)
        {
            claimsIdentity.AddClaim(
                new Claim(ClaimTypes.Role, role));
        }

        ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(claimsIdentity);

        HttpContext.Current.User = claimsPrincipal;
    }
}

这篇关于基于声明的表单身份验证角色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆