Question Comment intercepter 401 de l'authentification par formulaire dans ASP.NET MVC?


Je souhaite générer une page 401 si l'utilisateur ne dispose pas des droits requis.

L'utilisateur demande une URL et est redirigé vers la page de connexion (j'ai tout nier dans web.config). L'utilisateur se connecte avec succès et est redirigé vers l'URL d'origine. Toutefois, lors de la vérification des autorisations, il est déterminé que l'utilisateur ne dispose pas des autorisations requises. Par conséquent, j'aimerais générer un 401. Mais l'authentification par formulaires gère toujours 401 et redirige l'utilisateur vers la page de connexion.

Pour moi, ce n'est pas correct. L'utilisateur a déjà authentifié, l'utilisateur n'a simplement pas le bon autorisation.

Dans d'autres scénarios, comme dans le scénario de service ajax ou REST, je ne veux absolument pas que la page de connexion - j'ai besoin de la page 401 appropriée.

Jusqu'à présent, j'ai essayé le filtre Authorize personnalisé pour renvoyer ViewResult avec 401 mais cela n'a pas fonctionné. J'ai ensuite essayé un filtre d'action normal, remplaçant OnActionExecuting, qui ne fonctionnait pas non plus.

Ce que j'ai pu faire, c'est gérer un événement dans global.asax, PostRequestHandlerExecute et vérifier la permission, puis écrire directement à la réponse:

if (permissionDenied)
{
    Context.Response.StatusCode = 401;
    Context.Response.Clear();
    Context.Response.Write("Permission Denied");
    Context.Response.Flush();
    Context.Response.Close();
    return;
}

Cela fonctionne mais ce n'est pas vraiment ce que je veux. Tout d'abord, je ne suis même pas sûr que ce soit le bon événement ou l'endroit dans le pipeline pour le faire. Deuxièmement, je veux que la page 401 ait un peu plus de contenu. De préférence, il devrait s'agir d'une page aspx avec éventuellement la même page maître que le reste du site. De cette manière, toute personne naviguant sur le site peut voir que l'autorisation est refusée, mais avec le même aspect, etc., mais l'utilisateur ajax ou le service recevra le code de statut approprié pour agir.

Une idée de comment cela peut être réalisé? J'ai vu d'autres publications avec des demandes similaires mais je n'ai pas vu de solution que je puisse utiliser.

Et non, je ne veux pas un 403.


14
2018-05-28 19:05


origine


Réponses:


J'ai trouvé une solution viable.

401 rediriger par FormsAuthenticationModule se produit pendant EndRequest. Depuis lors, lors du traitement des événements, les modules sont appelés avant global.asax, nous pouvons remplacer le code d'état après FormsAuthenticationModule a eu ses mains sales sur la demande.

Dans mon AuthorizationFilter personnalisé, j'ai défini HttpContext.Items ["PermissionDenied"] à vrai puis dans mon global.asax  EndRequest, Je retourne le code d'état de 200 à 401. Puis je Server.Transfer à ma vue PermissionDenied personnalisée.

Je préférerais encore FormsAuthenticationModule lui-même a été mis à jour pour gérer ce scénario, mais je pense que ce n'est pas trop piraté que je pense que je peux vivre avec elle.

De toute évidence, vous pouvez changer la façon dont vous signalez que global.asax devrait retourner le code d'état. Je viens d'essayer de définir le code d'état à quelque chose comme 511 et l'a utilisé comme condition plutôt que HttpContext.Items et ça a aussi bien fonctionné. Je suppose que tant que le code de statut correct sort de la porte, le moteur ASP.NET ne se soucie pas.


8
2018-05-28 22:12



HttpContext.Current.Response.SuppressFormsAuthenticationRedirect = true;

5
2018-02-10 08:34



Je suis d'accord que le comportement par défaut est faux, en particulier compte tenu des demandes Ajax. J'espère voir une sorte de solution dans MVCv3 (doigts croisés).

La seule façon que je sache pour y parvenir est de supprimer la section Authentification du fichier web.config. C'est ce que recherche ASP.NET pour rediriger les requêtes non autorisées. Vous ne pouvez pas désactiver cette "fonctionnalité" à ma connaissance. Si vous avez une section d’authentification, vous serez redirigé vers l’URL de connexion si ASP.NET rencontre un 401 code de statut.

Mais en supprimant cela, vous avez d'autres problèmes. Si vous souhaitez que l'utilisateur soit redirigé vers la page de connexion pour les demandes non ajax, vous devrez implémenter votre propre AuthorizeAttribute et utilisez des paramètres personnalisés pour déterminer où rediriger. De plus, tout autre élément de la section Authentification devra probablement être réimplémenté par vous. Pas une solution très pratique dans les sites compliqués.

Je ne l'ai pas fait moi-même, j'ai décidé de retourner un 403 au lieu. Il est énervant de ne pas avoir le bon HttpCode, mais c'est mieux que toute autre solution que j'ai trouvée jusqu'ici.


2
2018-05-28 20:21



Vous pourriez vouloir regarder ici: ASP.NET MVC Gestion des erreurs personnalisée Application_Error Global.asax?

Vous devriez être capable d'attraper le 401 et d'acheminer vers une action personnalisée à ce stade. Nous faisons cela pour 404 et autres exceptions dans notre code, et cela fonctionne très bien.


0
2018-05-28 19:18