在ASP.NET MVC 4中使用aspnet身份进行基于角色的身份验证

时间:2015-02-06 07:37:26

标签: c# asp.net asp.net-mvc-4 authentication asp.net-identity

我正在创建ASP.NET MVC 4 Internet Application。

在该应用程序中,我创建了任何用户都可以登录的登录页面,然后我允许根据用户的角色将用户重定向到不同的页面。

ASP.NET Identity是这里的会员系统。

这是我的登录控制器方法:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        var user = await UserManager.FindAsync(model.UserName, model.Password); 

        if (user != null)
        {
            if (user.ConfirmedEmail == true)
            {

                await SignInAsync(user, model.RememberMe);

                if (String.IsNullOrEmpty(returnUrl))
                {
                    if (UserManager.IsInRole(user.Id, "HEC_Admin"))
                    {
                        return RedirectToAction("Index", "HEC");
                    }
                    //role Admin go to Admin page
                    if (UserManager.IsInRole(user.Id, "HEI_User"))
                    {
                        return RedirectToAction("Index", "HEI");
                    }
                }

                else
                {
                    return RedirectToLocal(returnUrl);
                }


            }
            else
            {
                ModelState.AddModelError("", "Confirm Email Address.");
            }
        }
        else
        {
            ModelState.AddModelError("", "Invalid username or password.");
        }
    }
    // If we got this far, something failed, redisplay form
    return View(model);
}

这是HEI控制器类:

public class HEIController : Controller
{
    //
    // GET: /HEI/

   [Authorize(Roles = "HEI_User")]
    public ActionResult Index()
    {
        return View();
    }



}

这是我的HEC控制器类:

     public class HECController : Controller

    {
        //
        // GET: /HEC/
       [Authorize(Roles = "HEC_Admin")]
       public ActionResult Index()
        {
            return View();
        }
   }

当我删除HECController类中的索引操作上方的 [Authorize(Roles =“HEC_Admin”)] 时以及当我删除 [Authorize(Roles =“HEC_User”)] 在HEIController类的索引操作之上,这个工作正常,

但是那么如何限制对这些页面的未经授权的访问?

1 个答案:

答案 0 :(得分:2)

我和你有同样的问题,我仍然不知道它发生的原因。我所做的是创建自己的自定义授权属性并自己检查角色。

public class CustomAuthorizationAttribute : AuthorizeAttribute
{
    public string IdentityRoles
    {
        get { return _identityRoles ?? String.Empty; }
        set
        {
            _identityRoles = value;
            _identityRolesSplit = SplitString(value);
        }
    }

    private string _identityRoles;
    private string[] _identityRolesSplit = new string[0];

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        //do the base class AuthorizeCore first
        var isAuthorized = base.AuthorizeCore(httpContext);
        if (!isAuthorized)
        {
            return false;
        }
        if (_identityRolesSplit.Length > 0)
        {
            //get the UserManager
             using(var um = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
            {
                var id = HttpContext.Current.User.Identity.GetUserId();
                //get the Roles for this user
                var roles = um.GetRoles(id);
                //if the at least one of the Roles of the User is in the IdentityRoles list return true
                if (_identityRolesSplit.Any(roles.Contains))
                {
                    return true;
                }
            }
            return false;
        }
        else
        {
            return true;
        }

    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        //if the user is not logged in use the deafult HandleUnauthorizedRequest and redirect to the login page
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
        else
        //if the user is logged in but is trying to access a page he/she doesn't have the right for show the access denied page
        {
            filterContext.Result =  new RedirectResult("/AccessDenied");
        }
    }

    protected static string[] SplitString(string original)
    {
        if (String.IsNullOrEmpty(original))
        {
            return new string[0];
        }

        var split = from piece in original.Split(',')
                    let trimmed = piece.Trim()
                    where !String.IsNullOrEmpty(trimmed)
                    select trimmed;
        return split.ToArray();
    }
}

如果用户已登录但无法访问此操作或控制器,我还添加了HandleUnauthorizedRequest方法以重定向到适当的页面

要使用它,请执行以下操作:

[CustomAuthorization(IdentityRoles = "HEI_User")]
public ActionResult Index()
{
    return View();
}

希望它有所帮助。