Estoy creando un sitio web multicliente que aloja páginas para clientes. El primer segmento de la URL será una cadena que identifica al cliente, definida en Global.asax utilizando el siguiente esquema de enrutamiento de URL:
"{client}/{controller}/{action}/{id}"
Esto funciona bien, con URL como / foo / Home / Index.
Sin embargo, cuando uso el atributo [Autorizar], quiero redirigir a una página de inicio de sesión que también usa el mismo esquema de asignación. Entonces, si el cliente es foo, la página de inicio de sesión sería / foo / Account / Login en lugar de la redirección fija / Account / Login definida en web.config.
MVC usa un HttpUnauthorizedResult para devolver un estado 401 no autorizado, que supongo hace que ASP.NET redirija a la página definida en web.config.
Entonces, ¿alguien sabe cómo anular el comportamiento de redireccionamiento de inicio de sesión de ASP.NET? ¿O sería mejor redirigir en MVC creando un atributo de autorización personalizado?
EDITAR - Respuesta: después de investigar un poco la fuente .Net, decidí que un atributo de autenticación personalizado es la mejor solución:
public class ClientAuthorizeAttribute: AuthorizeAttribute
{
public override void OnAuthorization( AuthorizationContext filterContext )
{
base.OnAuthorization( filterContext );
if (filterContext.Cancel && filterContext.Result is HttpUnauthorizedResult )
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "client", filterContext.RouteData.Values[ "client" ] },
{ "controller", "Account" },
{ "action", "Login" },
{ "ReturnUrl", filterContext.HttpContext.Request.RawUrl }
});
}
}
}
Respuestas:
Creo que el problema principal es que si va a aprovechar la clase integrada de ASP.NET FormsAuthentication (y no hay una buena razón por la que no debería hacerlo), algo al final del día llamará a
FormsAuthentication.RedirectToLoginPage()
cuál para mirar la URL configurada. Solo hay una URL de inicio de sesión, y así es como la diseñaron.Mi intento por resolver el problema (posiblemente una implementación de Rube Goldberg) sería permitir que se redirija a una única página de inicio de sesión en la raíz compartida por todos los clientes, digamos / account / login. Esta página de inicio de sesión en realidad no mostraría nada; inspecciona el parámetro ReturnUrl o algún valor que tengo en la sesión o una cookie que identifica al cliente y lo usa para emitir una redirección 302 inmediata a la página específica / cliente / cuenta / inicio de sesión. Es una redirección adicional, pero probablemente no se perciba y le permite utilizar los mecanismos de redirección integrados.
La otra opción es crear su propio atributo personalizado como lo describe y evitar cualquier cosa que llame al
RedirectToLoginPage()
método en laFormsAuthentication
clase, ya que lo reemplazará con su propia lógica de redireccionamiento. (Puede crear su propia clase que sea similar). Dado que es una clase estática, no conozco ningún mecanismo mediante el cual pueda inyectar su propia interfaz alternativa y hacer que funcione mágicamente con el atributo [Autorizar] existente, que golpes, pero la gente ha hecho cosas similares antes .¡Espero que ayude!
fuente
Application_AuthenticateRequest
(consulte mi respuesta a continuación).En la versión RTM de ASP.NET MVC, falta la propiedad Cancelar. Este código funciona con ASP.NET MVC RTM:
Editar: Es posible que desee deshabilitar la URL de inicio de sesión de autenticación de formularios predeterminada en web.config, en caso de que alguien olvide que tiene un atributo personalizado y use el atributo [Autorizar] integrado por error.
Modifique el valor en web.config:
Luego, cree un método de acción 'ERROR' que registre un error y redirija al usuario a la página de inicio de sesión más genérica que tenga.
fuente
Mi solución a este problema fue una
ActionResult
clase personalizada :fuente
Aún así, si uno decide usar la autenticación de formularios ASP.NET incorporada, se puede anular
Application_AuthenticateRequest
de laGlobal.asax.cs
siguiente manera:fuente