Je crée un site Web mutualisé qui héberge des pages pour les clients. Le premier segment de l'URL sera une chaîne qui identifie le client, définie 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.
Cependant, lorsque j'utilise l'attribut [Authorize], je souhaite rediriger 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 serait / 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 suppose, oblige ASP.NET à rediriger vers la page définie dans web.config.
Alors, est-ce que quelqu'un sait comment remplacer le comportement de redirection de connexion ASP.NET? Ou serait-il préférable de rediriger dans MVC en créant un attribut d'autorisation personnalisé?
EDIT - Réponse: après quelques fouilles dans la source .Net, j'ai décidé qu'un attribut d'authentification personnalisé était la meilleure solution:
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 }
});
}
}
}
Réponses:
Je pense que le principal problème est que si vous allez utiliser la classe ASP.NET FormsAuthentication intégrée (et il n'y a aucune bonne raison que vous ne devriez pas), quelque chose à la fin de la journée va appeler
FormsAuthentication.RedirectToLoginPage()
qui va pour regarder l'URL configurée. Il n'y a qu'une seule URL de connexion, jamais, et c'est ainsi qu'ils l'ont conçue.Mon essai au problème (peut-être une implémentation de Rube Goldberg) serait de le laisser rediriger vers une seule page de connexion à la racine partagée par tous les clients, par exemple / compte / login. Cette page de connexion n'afficherait rien; il inspecte le paramètre ReturnUrl ou une valeur que j'ai dans la session ou un cookie qui identifie le client et l'utilise pour émettre une redirection 302 immédiate vers la page spécifique / client / account / login. C'est une redirection supplémentaire, mais probablement pas perceptible et elle vous permet d'utiliser les mécanismes de redirection intégrés.
L'autre option est de créer votre propre attribut personnalisé pendant que vous décrivez et d'éviter tout ce qui appelle la
RedirectToLoginPage()
méthode sur laFormsAuthentication
classe, car vous le remplacerez 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'attribut [Authorize] existant, qui coups, mais les gens ont déjà fait des choses similaires .J'espère que cela pourra aider!
la source
Application_AuthenticateRequest
(voir ma réponse ci-dessous).Dans la version RTM d'ASP.NET MVC, la propriété Cancel est manquante. Ce code fonctionne avec ASP.NET MVC RTM:
Edit: Vous pouvez désactiver l'authentification par formulaire par défaut loginUrl dans web.config - au cas où quelqu'un oublie que vous avez un attribut personnalisé et utilise l'attribut intégré [Authorize] par erreur.
Modifiez la valeur dans web.config:
Ensuite, créez une méthode d'action «ERREUR» qui enregistre une erreur et redirige l'utilisateur vers la page de connexion la plus générique que vous avez.
la source
Ma solution à ce problème était une
ActionResult
classe personnalisée :la source
Pourtant, si l' on décide d'utiliser le ASP.NET FormsAuthentication intégré, on peut overide
Application_AuthenticateRequest
dans laGlobal.asax.cs
manière suivante:la source