2012-02-20 16 views
11

Estoy tratando de hacer alguna autorización personalizada, así que creé un controlador que reemplaza el método OnAuthorization. También apliqué el atributo Authorize a este controlador. La pregunta es ¿por qué se llama al método OnAuthorization ANTES del proceso de autenticación de formularios básicos?¿Por qué onAuthorization se ejecuta antes de la autenticación?

Me gustaría autorizar al usuario luego de que se haya autenticado. ¿Me estoy perdiendo algo?

Aquí está el código:

[Authorize] 
    public class AuthorizationController : Controller 
    { 
     protected override void OnAuthorization(AuthorizationContext filterContext) 
     { 
      base.OnAuthorization(filterContext); 

      if (filterContext == null) 
      { 
       throw new ArgumentNullException("filterContext"); 
      } 

      List<string> allowedControllers = new List<string>() { "SecurityController" }; 
      List<string> allowedActions = new List<string>() { "Index" }; 

      string controllerName = filterContext.Controller.GetType().Name; 
      string actionName = filterContext.ActionDescriptor.ActionName; 

      if (!allowedControllers.Contains(controllerName) 
      || !allowedActions.Contains(actionName)) 
      { 
       filterContext.Result = View("UnauthorizedAccess"); 
      } 
     } 
    } 

El controlador que he probado con algo así como:

public class SecurityController : AuthorizationController 
{ 

    public ActionResult Index() 
    { 
     return View(); 
    } 

    public ActionResult AnotherIndex() 
    { 
     return View(); 
    } 
} 

Respuesta

15

Una de las primeras cosas que el AuthorizeAttribute hace es comprobar para ver si el usuario es autenticado . Si no lo son, entonces es cuando se emitirá un redireccionamiento a la página de inicio de sesión.

El AuthorizeAttribute básicamente envuelve la autenticación de registro de entrada con la pieza de autorización:

protected virtual bool AuthorizeCore(HttpContextBase httpContext) { 
     if (httpContext == null) { 
      throw new ArgumentNullException("httpContext"); 
     } 

     IPrincipal user = httpContext.User; 
     if (!user.Identity.IsAuthenticated) { 
      return false; 
     } 

Cuando se utiliza la AuthorizeAttribute sin roles/usuarios como lo hace en su ejemplo ([Autorizar]), que es básicamente sólo verificando para asegurarse de que el usuario esté autenticado en este caso.

Probablemente cambie su código para reemplazar el atributo AuthorizeAttribute en lugar de hacer este código en su controlador. Puede hacer lo siguiente:

public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     filterContext.Result = CreateResult(filterContext); 
    } 

    protected ActionResult CreateResult(AuthorizationContext filterContext) 
    { 
     var controllerContext = new ControllerContext(filterContext.RequestContext, filterContext.Controller); 
     var controller = (string)filterContext.RouteData.Values["controller"]; 
     var action = (string)filterContext.RouteData.Values["action"]; 
     // any custom model here 
     var model = new UnauthorizedModel(); 

     // custom logic to determine proper view here - i'm just hardcoding it 
     var viewName = "~/Views/Shared/Unauthorized.cshtml"; 

     return new ViewResult 
     { 
      ViewName = viewName, 
      ViewData = new ViewDataDictionary<UnauthorizedModel>(model) 
     }; 
    } 
} 
+0

Bueno, no sucede como esperaba. Para el ejemplo anterior, cuando deseo acceder a la acción AnotherIndex, esperaría obtener la página de inicio de sesión, pero obtendré Acceso no autorizado. – misha

+0

Después de su edición: entiendo, pero si anulo el AuthorizeAttribute, no tengo acceso para realizar otras acciones, como redirigir al usuario a una página que le dice que no está autorizado en lugar de no haber iniciado sesión ... – misha

+0

@misha Seguro lo haces. ¿Qué te hace pensar que no puedes? – Dismissile

-2
public override void OnAuthorization(AuthorizationContext filterContext) 
{ 
    base.OnAuthorization(filterContext); 
    bool flag = false; 
    string UserId; 
    string[] AssignedRights = null; 

    //Check if Http Context Contains User Name 
    if (HttpContext.Current.User.Identity.Name != null && HttpContext.Current.User.Identity.Name != string.Empty) 
    { 
     //Get User Id from HttpContext 
     UserId = HttpContext.Current.User.Identity.Name; 
     RoleRepository roleRepository = new RoleRepository(); 
     AssignedRights = roleRepository.GetRolesByUser(Convert.ToInt32(UserId)); 
     flag = IsUserAuthorized(filterContext, flag, AssignedRights); 

     if (flag == false) 
     { 

      filterContext.Result = new HttpUnauthorizedResult(); 
     } 
    } 

} 
0

A continuación se presenta una muestra de Autorización atributo personalizado.

public class AuthLogAttribute:AuthorizeAttribute 
    { 

     public string View { get; set; } 

     public AuthLogAttribute() 
     { 
      View = "AuthorizeFailed"; 
     } 
     public override void OnAuthorization(AuthorizationContext filterContext) 

     { 
      base.OnAuthorization(filterContext); 
      IsUserAuthorized(filterContext); 
     } 

     private void IsUserAuthorized(AuthorizationContext filterContext) 
     { 
      // If the Result returns null then the user is Authorized 
      if(filterContext.Result ==null) 
       return; 

      //If the user is Un-Authorized then Navigate to Auth Failed View 
      if(filterContext.HttpContext.User.Identity.IsAuthenticated) 

      { 
       var vr = new ViewResult(); 
       vr.ViewName = View; 

       ViewDataDictionary dict = new ViewDataDictionary(); 
       dict.Add("Message", "Sorry you are not Authorized to Perform this Action"); 
       vr.ViewData = dict; 

       var result = vr; 
       filterContext.Result = vr; 
      } 

     } 
    } 

su controlador será como siguiente,

[AuthLog(Roles ="Manager")]  
     public ActionResult Create() 
     { 
      var product = new Product(); 
      return View(product); 
     } 

finalmente crear nueva vista compartida llamada "AuthorizeFailed".

Cuestiones relacionadas