如何使用授权属性从我的控制器重定向?

时间:2013-05-31 07:54:19

标签: asp.net-mvc authorize-attribute

我已AuthorizeAttributeBase扩展AuthorizeAttribute。 它看起来像这样:

public abstract class MyAuthorizeAttribute : AuthorizeAttribute
{
//Holds the roles allowed to perform the action.
public IEnumerable<string> roles { get; set; }

/// <summary>
/// Authorizes if the current user may perform the action
/// </summary>
/// <param name="httpContext">Unused - included for override purposes.</param>
/// <returns>true if authorized.</returns>
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
    //Return true if user is in the action allowed roles.
    if (IsUserInRole)
    {
        return true;
    }
    else
    {
        HttpContext.Current.Response.StatusCode = 401;
        return false;
    }
}

/// <summary>
/// Checks if the user is member of a role that is allowed by the authorization
/// </summary>
public bool IsUserInRole
{
    get
    {
        if (roles != null)
        {
            //Check if any of the roles in the session is in the list of roles of the authorization
            return (MySessionGetter.GetSession().Roles.Intersect<string>(roles).Any());
        }
        //If none of the roles match return false.
        return false;
    }
}

/// <summary>
/// Sets the allowed roles of the authorization
/// </summary>
/// <param name="userRoles">Allowed roles</param>
public void AlowedRoles(IEnumerable<string> userRoles)
{
    roles = userRoles;
}

我保留允许的角色名称:

/// <summary>
/// Holds the role names.
/// </summary>
public static class UserRoles
{
    public static string Administrators = "Administrators";
    public static string Teachers= "Teachers";
}

并像我一样使用我的基地:

/// <summary>
/// Authorization for the access to the SomeAction 
/// </summary>
public class AuthorizeAccessToSomeActionAttribute : MyAuthorizeAttribute
{
    public AuthorizeAccessToSomeActionAttribute()
    {
        AlowedRoles(new List<string> {  UserRoles.Adminstrators, 
                                            UserRoles.Teachers });
    }
}    

最后但并非最不重要的是控制器:

    /// <summary>
    /// The main Index view of application
    /// </summary>
    /// <returns>Application Index views</returns>
    [AuthorizeAccessToSomeAction]
    public ActionResult Index()
    {
            return View("Index");
    }

现在我要做的是在AuthorizeAttribute s的基础上使索引开关返回值。 让教师向TeachersIndex()和管理员说AdministratorsIndex()

我尝试将其添加到基地:

//Checks if the current user is authorized. 
public bool IsAuthorized()
{
    return AuthorizeCore(new HttpContextWrapper());
}

但我最终每次都要创建新的AutorizeAttribute。 让它static似乎给了我更多的问题。

有没有正确的方法来解决这个问题?


解决了它。 :) OnAuthorization覆盖让我获得了新的领先优势。 找到了这个question

我将重定向放在Dictionary<string, RedirectToRouteResult>中,因为我喜欢将所有角色字符串保存在一个地方而不是用魔术字符串填充控制器的想法。

public static Dictionary<string, RedirectToRouteResult>     HomeRedirect
    {
        get
        {
            return new Dictionary<string, RedirectToRouteResult> {
                {"Administrators", new RedirectToRouteResult(
                    new RouteValueDictionary { { "action", "AdministratorIndex" }, { "controller", "MyController" }})},
                {"Teacher", new RedirectToRouteResult(
                    new RouteValueDictionary { { "action", "TeacherIndex" }, { "controller", "MyController" }})}
};

override HandleUnauthorizedRequest现在看起来像这样:

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
        filterContext.Result = UserRoles.HomeRedirect
            .SingleOrDefault(m => m.Key == MySessionGetter.GetSession().Roles.First()).Value;
    }

1 个答案:

答案 0 :(得分:2)

看看RedirectToRouteResult和RedirectResult。 这将是一个良好的开端:

// Redirects users of given role to given action
public class AuthorizeAccessToSomeActionAttribute : MyAuthorizeAttribute
{
    public string Role { get; set; }
    public string RedirectToAction { get; set; }

    public AuthorizeAccessToSomeActionAttribute(string role, string action)
    {
        Role = role;
        RedirectToAction = action;
    }
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
       // Test if current user is in the role
       if (filterContext.HttpContext.User.IsInRole(Role))
       {
            // Get current routevalues
            var rvals = filterContext.RouteData.Values;
            // Change action
            rvals["action"] = RedirectToAction;
            filterContext.Result = new RedirectToRouteResult("Default",rvals);
       }
    }
} 

用法:

    // Redirect role to given action
    [AuthorizeAccessToSomeActionAttribute("Teacher", "TeacherIndex" )]
    [AuthorizeAccessToSomeActionAttribute("Admin", "AdminIndex" )]
    public ActionResult Index()
    ...
    public ActionResult TeacherIndex()
    ...
    public ActionResult AdminIndex()