0

我创建了一个自定义的角色基​​础授权属性。我的想法是,当角色名称为“员工”的用户登录时,不应允许通过 URL 访问“管理员”页面。但是当我实现[MyRoleAuthorization]in Employee 控制器并登录时,错误显示“这个网页有一个重定向循环”。这是代码[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());
    }

你能帮我么。

4

3 回答 3

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());
}
于 2014-01-06T02:52:42.747 回答
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();
    }
}

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

于 2014-01-06T02:54:13.637 回答
0

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

无限循环。

于 2014-01-06T02:51:47.763 回答