授权属性在MVC中不起作用

时间:2015-06-23 19:42:53

标签: asp.net-mvc asp.net-mvc-4 authorization roles

我有一个角色为Member的用户。我有这个登录操作:

public virtual ActionResult Login(string returnUrl)
{
    if(User.Identity.IsAuthenticated)
    {
        if (IsValidReturnUrl(returnUrl))
            return Redirect(returnUrl);
        return Redirect(FormsAuthentication.DefaultUrl);
    }
    return View();
}

我有这个ActionMethod:

[Authorize(Roles="Member")]
public virtual ActionResult PostLostThing()
{
    var maingroups = _maingroups.SelectAll();
    var Provinces = _provinces.SelectAll();
    ViewBag.MainGroups = new SelectList(maingroups, "GroupId", "GroupName", maingroups.FirstOrDefault().GroupId);
    ViewBag.SubGroups = new SelectList(maingroups.FirstOrDefault().SubGroups, "id", "name");
    ViewBag.Provinces = new SelectList(Provinces, "Id", "Title", Provinces.FirstOrDefault().Id);
    ViewBag.Cities = new SelectList(Provinces.FirstOrDefault().Cities, "Id", "Name");

    return View();
}

当用户登录并呼叫视图PostLostThing时,它会重定向到登录页面,但当Role Authorize属性被删除时,它的效果非常好。我有这个SetAuthCookie方法:

private void SetAuthCookie(string memberName, string roleofMember, bool presistantCookie)
{
    var timeout = presistantCookie ? FormsAuthentication.Timeout.TotalMinutes : 30;

    var now = DateTime.UtcNow.ToLocalTime();
    var expirationTimeSapne = TimeSpan.FromMinutes(timeout);

    var authTicket = new FormsAuthenticationTicket(
        1,
        memberName,
        now,
        now.Add(expirationTimeSapne),
        presistantCookie,
        roleofMember,
        FormsAuthentication.FormsCookiePath
        );

    var encryptedTicket = FormsAuthentication.Encrypt(authTicket);

    var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
    {
        HttpOnly = true,
        Secure = FormsAuthentication.RequireSSL,
        Path = FormsAuthentication.FormsCookiePath
    };

    if (FormsAuthentication.CookieDomain != null)
    {
        authCookie.Domain = FormsAuthentication.CookieDomain;
    }

    if (presistantCookie)
        authCookie.Expires = DateTime.Now.AddMinutes(timeout);

    Response.Cookies.Add(authCookie);
}

有什么问题?

1 个答案:

答案 0 :(得分:0)

由于您自己设置了auth cookie,因此需要在Global.asax.cs文件中实现Application_AuthenticateRequest。否则,除了用户名之外的任何内容都不会添加到Principal对象中。

以下是一个示例实现:

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 = null;

        GenericPrincipal userPrincipal = new GenericPrincipal(new GenericIdentity(authTicket.Name), roles);
        Context.User = userPrincipal;
    }
}

您使用的重载假定您传递的值roleofMember实际上是一些序列化数据。然后,您需要告诉它如何处理反序列化该用户数据。由于您只是传递一个角色名称,因此您可以将上面的示例修改为:

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 = new string [] { authTicket.UserData };

        GenericPrincipal userPrincipal = new GenericPrincipal(new GenericIdentity(authTicket.Name), roles);
        Context.User = userPrincipal;
    }
}