带有角色的MVC 4中的自定义授权属性

时间:2014-01-06 02:35:57

标签: c# asp.net asp.net-mvc-4 asp.net-authorization

我已经创建了一个自定义的角色基​​本授权属性。我的想法是,当不允许角色名为“employee”的用户登录时,可以通过URL访问“admin”页面。但是当我在Employee控制器中实现[MyRoleAuthorization]并登录时,错误显示“此网页有重定向循环”。 这是[MyRoleAuthorization]

的代码
public class MyRoleAuthorization : AuthorizeAttribute
{
    string isAuthorized;
    private string AuthorizeUser(AuthorizationContext filterContext)
    {
        if (filterContext.RequestContext.HttpContext != null)
        {
            var context = filterContext.RequestContext.HttpContext;


            if (Convert.ToString(context.Session["RoleName"]) == "Admin")
            {
                isAuthorized = "Admin";

            }
            else if (Convert.ToString(context.Session["RoleName"]) == "Employee")
            {
                isAuthorized = "Employee";

            }
            else if (Convert.ToString((context.Session["RoleName"])) == "Customer")
            {
                isAuthorized = "Customer";
            }
            else
            {
                throw new ArgumentException("filterContext");
            }
        }
        return isAuthorized;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
            throw new ArgumentException("filterContext");

        if (AuthorizeUser(filterContext) == "Admin")
        {
            filterContext.Result = new RedirectToRouteResult
                 (new RouteValueDictionary(new { controller = "Admin" }));
        }

        else if (AuthorizeUser(filterContext) == "Employee")
        {
            filterContext.Result = new RedirectToRouteResult
                 (new RouteValueDictionary(new { controller = "Employee" }));
        }
        else if (AuthorizeUser(filterContext) == "Customer")
        {
            filterContext.Result = new RedirectToRouteResult
                 (new RouteValueDictionary(new { controller = "Customer" }));

        }
    }

}
} 

我的员工控制器看起来像这样

   [MyRoleAuthorization]        
    public ActionResult Index()
    {
        var employee = db.Employee.Include(e => e.User);
        return View(employee.ToList());
    }
你能帮我吗?

3 个答案:

答案 0 :(得分:1)

您最大的问题是,当您作为员工转到员工控制器时,您将被重定向到员工控制器,您的属性会将您重定向到员工控制器等等。尽量避免在属性中重定向,因为它会使代码变得脆弱。当你多年回来时,你将不记得为什么你的路线不能像你想要的那样工作

试试这个:

public class MyRoleAuthorization : AuthorizeAttribute
{

    public string Role{get;set;}

    private string AuthorizeUser(AuthorizationContext filterContext)
    {
        if (filterContext.RequestContext.HttpContext != null)
        {
            var context = filterContext.RequestContext.HttpContext;

            return (string)context.Session["RoleName"];
        }
        throw new ArgumentException("filterContext");
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
            throw new ArgumentException("filterContext");

        var role = AuthorizeUser(filterContext);
        if (role.Equals(Role))
        {
        // insert positive outcome from role check, ie let the action continue
        }
        else
        {
        // denied! redirect to login page or show denied page (403)
        }
    }
} 


[MyRoleAuthorization("Employee")]        
public ActionResult Index()
{
    var employee = db.Employee.Include(e => e.User);
    return View(employee.ToList());
}

答案 1 :(得分:1)

您的重定向代码始终会将用户重定向到“员工索引操作”,即使您重定向到的操作已为该员工进行身份验证。您需要在授权中提供另一组规则并更改OnAuthorize方法。

public class MyRoleAuthorization : AuthorizeAttribute
{
/// <summary>
/// the allowed types
/// </summary>
readonly string[] allowedTypes;

/// <summary>
/// Default constructor with the allowed user types
/// </summary>
/// <param name="allowedTypes"></param>
public MyRoleAuthorization(params string[] allowedTypes)
{
    this.allowedTypes = allowedTypes;
}

/// <summary>
/// Gets the allowed types
/// </summary>
public string[] AllowedTypes
{
    get { return this.allowedTypes; }
}

/// <summary>
/// Gets the authorize user
/// </summary>
/// <param name="filterContext">the context</param>
/// <returns></returns>
private string AuthorizeUser(AuthorizationContext filterContext)
{
    if (filterContext.RequestContext.HttpContext != null)
    {
        var context = filterContext.RequestContext.HttpContext;
        string roleName = Convert.ToString(context.Session["RoleName"]);
        switch (roleName)
        {
            case "Admin":
            case "Employee":
            case "Customer":
                return roleName;
            default:
                throw new ArgumentException("filterContext");
        }
    }
    throw new ArgumentException("filterContext");
}

/// <summary>
/// The authorization override
/// </summary>
/// <param name="filterContext"></param>
public override void OnAuthorization(AuthorizationContext filterContext)
{
    if (filterContext == null)
        throw new ArgumentException("filterContext");
    string authUser = AuthorizeUser(filterContext);
    if (!this.AllowedTypes.Any(x => x.Equals(authUser, StringComparison.CurrentCultureIgnoreCase)))
    {
        filterContext.Result = new HttpUnauthorizedResult();
        return;
    }
}

}

然后可以将其装饰为

public class EmployeeController : Controller
{
    [MyRoleAuthorization("Employee")]
    public ActionResult Index()
    {
        return View();
    }
}

现在应修改您的登录代码,以便将用户发送到正确的控制器。

答案 2 :(得分:0)

例如,在获得授权后,您似乎会重定向到客户控制器。该控制器可能具有您的属性,因此它授权被视为客户的用户,并重定向到客户控制器...哪个具有您的属性,因此它授权用户...

无限循环。