Comment redirect vers une URL de connexion dynamic dans ASP.NET MVC

Je crée un site Web multi-locataires qui héberge des pages pour les clients. Le premier segment de l’URL sera une chaîne qui identifie le client, défini dans Global.asax à l’aide du schéma de routage d’URL suivant:

"{client}/{controller}/{action}/{id}" 

Cela fonctionne bien, avec des URL telles que / foo / Home / Index.

Toutefois, lorsque vous utilisez l’atsortingbut [Authorize], je souhaite redirect vers une page de connexion qui utilise également le même schéma de mappage. Donc, si le client est foo, la page de connexion sera / foo / Account / Login au lieu de la redirection fixe / Account / Login définie dans web.config.

MVC utilise un HttpUnauthorizedResult pour renvoyer un statut 401 non autorisé, ce qui, je présume, entraîne la redirection d’ASP.NET vers la page définie dans web.config.

Alors, quelqu’un sait-il comment remplacer le comportement de redirection de connexion ASP.NET? Ou serait-il préférable de redirect dans MVC en créant un atsortingbut d’autorisation personnalisé?

EDIT – Réponse: après quelques recherches dans la source .Net, j’ai décidé qu’un atsortingbut d’authentification personnalisé est la meilleure solution:

 public class ClientAuthorizeAtsortingbute: AuthorizeAtsortingbute { 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 } }); } } } 

Je pense que le principal problème est que si vous utilisez la classe ASP.NET FormsAuthentication intégrée (et il n’y a aucune raison de ne pas le faire), quelque chose à la fin de la journée va appeler FormsAuthentication.RedirectToLoginPage() qui va regarder l’URL configurée. Il n’ya qu’une seule URL de connexion, et c’est exactement ce qu’elles ont conçu.

Mon problème avec le problème (peut-être une implémentation Rube Goldberg) serait de le laisser redirect vers une seule page de connexion à la racine partagée par tous les clients, disons / account / login. Cette page de connexion n’affiche rien; il inspecte soit le paramètre ReturnUrl ou une valeur que j’ai dans la session, soit un cookie qui identifie le client et l’utilise pour émettre une redirection immédiate 302 vers la page spécifique / client / compte / connexion. C’est une redirection supplémentaire, mais probablement pas perceptible et vous permet d’utiliser les mécanismes de redirection intégrés.

L’autre option consiste à créer votre propre atsortingbut personnalisé à mesure que vous décrivez et à éviter tout ce qui appelle la méthode RedirectToLoginPage() sur la classe FormsAuthentication , car vous allez la remplacer par votre propre logique de redirection. (Vous pouvez créer votre propre classe similaire). Comme il s’agit d’une classe statique, je ne connais aucun mécanisme par lequel vous pourriez simplement injecter votre propre interface alternative et la faire fonctionner comme par magie avec l’atsortingbut [Authorize] existant, qui les coups, mais les gens ont fait des choses similaires avant .

J’espère que cela pourra aider!

Dans la version RTM de ASP.NET MVC, la propriété Cancel est manquante. Ce code fonctionne avec ASP.NET MVC RTM:

 using System; using System.Web; using System.Web.Mvc; using System.Web.Mvc.Resources; namespace ePegasus.Web.ActionFilters { public class CustomAuthorize : AuthorizeAtsortingbute { public override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); if (filterContext.Result is HttpUnauthorizedResult) { filterContext.Result = new RedirectToRouteResult( new System.Web.Routing.RouteValueDictionary { { "langCode", filterContext.RouteData.Values[ "langCode" ] }, { "controller", "Account" }, { "action", "Login" }, { "ReturnUrl", filterContext.HttpContext.Request.RawUrl } }); } } } } 

Modifier: vous pouvez désactiver l’authentification par formulaire par défaut loginUrl dans web.config – au cas où quelqu’un oublie un atsortingbut personnalisé et utilise l’atsortingbut [Authorize] intégré par erreur.

Modifiez la valeur dans web.config:

   

Ensuite, créez une méthode d’action “ERROR” qui enregistre une erreur et redirige l’utilisateur vers la page de connexion la plus générique que vous avez.

Ma solution à ce problème était une classe ActionResult personnalisée:

  sealed public class RequiresLoginResult : ActionResult { override public void ExecuteResult (ControllerContext context) { var response = context.HttpContext.Response; var url = FormsAuthentication.LoginUrl; if (!ssortingng.IsNullOrWhiteSpace (url)) url += "?returnUrl=" + HttpUtility.UrlEncode (ReturnUrl); response.Clear (); response.StatusCode = 302; response.RedirectLocation = url; } public RequiresLoginResult (ssortingng returnUrl = null) { ReturnUrl = returnUrl; } ssortingng ReturnUrl { get; set; } }