J'ai un site Web ASP.NET avec authentification avec ActiveDirectory.
Maintenant , lorsqu'un utilisateur authentifié ouvre une page - il est automatiquement authentifié. J'ai rencontré un problème - lorsqu'un utilisateur non authentifié (par exemple, un utilisateur de Mozilla Firefox avec une propriété network.automatic-ntlm-auth.trusted-uris
non définie) ouvre une page, IIS envoie une réponse 401 et demande une mot de passe.
Ce que je veux, c'est ne pas l'inviter à entrer son nom d'utilisateur\mot de passe - il suffit d'afficher une page d'erreur personnalisée. Cela semble assez simple - les utilisateurs authentifiés obtiennent la page demandée, les non authentifiés sont redirigés vers une page d'erreur personnalisée. Cela fonctionnerait bien pour FormsAuthentication.
Cependant, j'ai essayé tellement de façons maintenant. Les redirections Web.config ne fonctionnent pas. Même si j'efface une Response
et y mets une redirection, je vais obtenir une boucle car cette page personnalisée (* par exemple, /Error/AccessDenied
) requiert également une authentification. Marquer un contrôleur comme AllowAnonymous
ne fait rien.
Toutefois, si j'active l'authentification anonyme dans IIS Manager, les utilisateurs de domaine authentifiés authentifiés ne sont pas autorisés lorsqu'ils ouvrent un site Web.
Comment puis-je résoudre ce problème?
Merci à @Abhitalks pour avoir expliqué comment cela fonctionne dans les commentaires. Je ne sais pas pourquoi, mais j'étais sûr que IE et Google Chrome envoyaient un en-tête d'autorisation à la première demande. C'est pourquoi seuls les utilisateurs non autorisés obtiennent une réponse 401. Après avoir compris que je ne pouvais absolument pas éviter la réponse 401, j'ai décidé d'utiliser cette approche simple car ce comportement est le plus proche de souhaitable.
J'ai ajouté la méthode suivante dans Global.asax
:
protected void Application_EndRequest(object sender, EventArgs e)
{
if (Response.StatusCode == 401)
{
Response.ClearContent();
Response.WriteFile("~/Static/NotAuthorized.html");
Response.ContentType = "text/html";
}
}
Désormais, lorsqu'un utilisateur ouvre une page, le serveur lui renvoie une page d'erreur personnalisée mais avec l'en-tête 401 Unauthorized
.
Chrome, IE ou Firefox bien configuré . Les utilisateurs demandent une URL, le serveur renvoie la page d'erreur avec l'en-tête 401 - un navigateur termine automatiquement le défi d'autorisation, redirige vers la même URL, le serveur renvoie la page correcte et 200 maintenant. L'utilisateur ne verra pas cette page d'erreur.
Firefox non configuré . L'utilisateur demande une URL, le serveur renvoie la page d'erreur avec l'en-tête 401 - un navigateur ne peut pas terminer le processus d'autorisation et invite l'utilisateur à fournir ses informations d'identification.
L'utilisateur entre le bon identifiant . L'utilisateur demande à nouveau la même URL, obtient une page et 200 OK.
L'utilisateur entre un identifiant incorrect . Un navigateur demande à nouveau les informations d'identification.
L'utilisateur appuie sur Annuler . Un navigateur affiche la page d'erreur personnalisée qui a été envoyée avec l'en-tête 401. Cette page indique à l'utilisateur que s'il utilise Firefox, il doit alors entrer ses informations d'identification ou autoriser l'authentification NTLM automatique.
Ajout important au commentaire de Yeldar:
Lors de la modification du message de réponse pour les requêtes distantes (read: non-localhost), vous devrez ajouter les éléments suivants à votre fichier de configuration:
<system.webServer>
<httpErrors existingResponse="PassThrough"></httpErrors>
</system.webServer>
Si vous ne permettez pas à la réponse de "passer par", les clients distants obtiendront le "You do not have permission to view this directory or page"
par défaut.
J'ai eu cette information de: https://stackoverflow.com/a/17324195/3310441
Remplacez la méthode HandleUnauthorizedRequest dans l'attribut Authorize.
Ex:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary (new {controller = "CustomError", action = "Unauthorized"}));
}