2013-05-31 2 views
2

Я сделал AuthorizeAttributeBase для продления AuthorizeAttribute. Это выглядит следующим образом:Как я могу перенаправить свой контроллер с помощью AuthorizeAttributes?

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; 
} 

Я держу разрешённые rolenames так:

/// <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 override дал мне новое преимущество. Найдено 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; 
    } 

ответ

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() 
Смежные вопросы