Contourner la redirection automatique de l'authentification par formulaire vers la connexion, comment faire ?

StackOverflow https://stackoverflow.com/questions/35322

Question

J'écris une application utilisant asp.net-mvc déployée sur iis6.J'utilise l'authentification par formulaire.Habituellement, lorsqu'un utilisateur tente d'accéder à une ressource sans autorisation appropriée, je souhaite qu'il soit redirigé vers une page de connexion.FormsAuth fait cela pour moi assez facilement.

Problème:Maintenant, j'ai une action accessible par une application console.Quel est le moyen le plus rapide de faire répondre cette action avec le statut 401 au lieu de rediriger la demande vers la page de connexion ?

Je veux que l'application console puisse réagir à ce 401 StatusCode au lieu qu'il soit transparent.J'aimerais également conserver le comportement par défaut, rediriger les demandes non autorisées vers le comportement de la page de connexion.

Note:À titre de test, j'ai ajouté ceci à mon global.asax et il n'a pas contourné l'authentification par formulaire :

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
    HttpContext.Current.SkipAuthorization = true;
}

@Dale et Andy

J'utilise le AuthorizeAttributeFilter fourni dans l'aperçu MVC 4.Cela renvoie un HttpUnauthorizedResult.Ce résultat définit correctement le statusCode sur 401.Le problème, si je comprends bien, est que asp.net intercepte la réponse (puisqu'elle est étiquetée comme 401) et la redirige vers la page de connexion au lieu de simplement la laisser passer.Je souhaite contourner cette interception pour certaines URL.

Était-ce utile?

La solution

Ok, j'ai contourné ce problème.J'ai créé un ActionResult personnalisé (HttpForbiddenResult) et un ActionFilter personnalisé (NoFallBackAuthorize).

Pour éviter la redirection, HttpForbiddenResult marque les réponses avec le code d'état 403.FormsAuthentication ne capte pas les réponses avec ce code, la redirection de connexion est donc effectivement ignorée.Le filtre NoFallBackAuthorize vérifie si l'utilisateur est autorisé, un peu comme le filtre Authorize inclus.Il diffère en ce sens qu'il renvoie HttpForbiddenResult lorsque l'accès est refusé.

Le HttpForbiddenResult est assez trivial :

public class HttpForbiddenResult : ActionResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        context.HttpContext.Response.StatusCode = 0x193; // 403
    }
}

Il ne semble pas possible d'ignorer la redirection de la page de connexion dans le FormsAuthenticationModule.

Autres conseils

Cela peut être une bidouille (et peut même ne pas fonctionner), mais sur votre page de connexion, voyez si Request.QueryString["ReturnUrl"] != null et si c'est le cas, définissez Response.StatusCode = 401.

Gardez à l’esprit que vous devrez toujours faire en sorte que votre application console s’authentifie d’une manière ou d’une autre.Vous n'obtenez pas l'authentification de base HTTP gratuitement :vous devez lancer le vôtre, mais il existe de nombreuses implémentations.

Avez-vous écrit votre propre attribut FormsAuth pour l'action ?Si tel est le cas, dans la méthode OnActionExecuting, le FilterExecutingContext vous est transmis.Vous pouvez l'utiliser pour renvoyer le code 401.

public class FormsAuth : ActionFilterAttribute
{
    public override void OnActionExecuting(FilterExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.StatusCode = 401;
        filterContext.Cancel = true;
    }
}

Cela devrait fonctionner.Je ne sais pas si vous avez écrit l'attribut FormsAuth ou si vous l'avez obtenu ailleurs.

Je n'ai pas encore utilisé AuthorizeAttribute fourni dans Preview 4.J'ai lancé le mien, car j'utilise le framework MVC depuis le premier CTP.J'ai jeté un coup d'œil rapide à l'attribut dans Reflector et il fait ce que j'ai mentionné ci-dessus en interne, sauf qu'ils utilisent l'équivalent hexadécimal de 401.Je devrai regarder plus loin dans l'appel, pour voir où l'exception est interceptée, car c'est très probablement là qu'ils effectuent la redirection.C'est la fonctionnalité que vous devrez remplacer.Je ne sais pas si vous pouvez le faire encore, mais je publierai lorsque je le trouverai et vous donnerai une solution, à moins que Haacked ne le voie et le publie lui-même.

J'ai fait quelques recherches sur Google et voici ce que j'ai trouvé :


    HttpContext.Current.Response.StatusCode = 401;

Je ne sais pas si cela fonctionne ou non, je ne l'ai pas testé.Quoi qu'il en soit, ça vaut le coup d'essayer, non ?:)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top