web-dev-qa-db-fra.com

Page d'erreur 401 personnalisée pour l'application ASP.NET MVC

J'ai créé une application ASP.NET MVC utilisant l'authentification Windows intégrée. La logique d'autorisation suivante a été implémentée:

  1. Essayez d'obtenir les informations d'identification du compte à partir d'Active Directory via NTLM.

    • Si les informations d'identification sont reçues et que le compte Windows dispose des autorisations requises, effectuez l'action demandée.
    • Sinon, passez à l'article 2.
  2. Affichez la boîte de dialogue d'authentification Windows afin qu'un utilisateur puisse fournir d'autres informations d'identification:  Authentication Dialog

    • Si d'autres informations d'identification sont reçues et que l'utilisateur dispose des autorisations requises, effectuez l'action demandée.
    • Si aucune autre information d'identification n'est reçue ou si les autorisations du compte sont inférieures à ce qui est requis, répétez la clause 2.
    • Si la boîte de dialogue d'authentification est annulée, un message d'erreur 401 s'affiche.

Ensuite, j'ai ajouté des pages d'erreur personnalisées pour l'application, à l'aide de la solution de VictorySaber :

protected void Application_EndRequest()
{
    int status = Response.StatusCode;
    string actionName;
    if (status >= 400 && status < 500)
    {
        switch (status)
        {
            case 401:
                actionName = "Unauthorized";
                break;

            // Handle another client errors

            default:
                actionName = "BadRequest";
                break;
            }
        }
    else if (status >= 500 && status < 600)
    {
        switch (status)
        {
            case 501:
                actionName  = "NotImplemented";
                break;

            // Handle another server errors

            default:
                actionName  = "InternalServerError";
                break;
        }
    }
    if (!String.IsNullOrEmpty(actionName))
    {
        Response.Clear();
        var rd = new RouteData();
        rd.Values["controller"] = "Errors";
        rd.Values["action"] = actionName;
        IController c = new ErrorsController();
        c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
    }
}

En conséquence, mes pages d'erreur conviviales sont rendues. Mais la boîte de dialogue d'authentification Windows n'apparaît pas. Si le code d'état HTTP 401 apparaît, il affiche immédiatement un message d'erreur 401. L'astuce avec la section <httpErrors> du fichier web.config donne le même résultat.

En outre, j'ai trouvé proposition pour intercepter le code d'état 401.2 HTTP qui devrait apparaître lorsque la boîte de dialogue est annulée. Mais dans mon cas, le code ne se produit jamais.

Comment utiliser des pages d'erreur conviviales au lieu des messages par défaut sans changer la logique du dialogue d'authentification?

Je dois implémenter les exigences suivantes:

  1. La boîte de dialogue d'authentification Windows apparaît uniquement pour un utilisateur dont le compte AD ne dispose pas des autorisations requises pour permettre à l'utilisateur de fournir d'autres informations d'identification.
  2. La boîte de dialogue apparaît alors que les informations d'identification correctes ne sont pas fournies ou que l'utilisateur ne les annule pas.
  3. La page d'erreur 401 personnalisée ne sera affichée que si l'utilisateur annule la boîte de dialogue.
7
Alexander

Un détail petit mais important a été omis. Par défaut, le serveur laisse la réponse intacte uniquement si l'indicateur SetStatus est défini. Donc, il est nécessaire de spécifier clairement ce que IIS doit faire avec une réponse existante lorsque le code d'état HTTP est une erreur.

Une solution consiste à configurer l'élément <httpErrors> de la section <system.webServer> dans le fichier Web.config. Définissez simplement existingResponse valeur d'attribut sur PassThrough, de sorte que le serveur laisse la réponse intacte si une réponse existante existe.

<system.webServer>

  <!-- configuration settings -->

  <httpErrors errorMode="Custom" existingResponse="PassThrough" />
</system.webServer>

La configuration empêche le rendu de la page d'erreur si le serveur demande des informations d'identification du compte d'utilisateur Windows. La réponse Sera remplacée par la page d'erreur après l'annulation de la boîte de dialogue.

Le même résultat pourrait être obtenu en désactivant IIS erreurs personnalisées via TrySkipIisCustomErrors propriété de HttpResponse. Ainsi, l'ajout de De la ligne suivante au code de la question résout le problème:

Context.Response.TrySkipIisCustomErrors = true;

Remarque . _ {La deuxième manière ne fonctionne pas sur mon serveur de production pour une raison quelconque. Je pense que cela nécessite des paramètres de serveur supplémentaires.} _

1
Alexander