272 votes

Pourquoi ne AuthorizeAttribute rediriger vers la page de connexion pour l'authentification et l'autorisation des échecs?

Dans ASP.NET MVC, vous pouvez marquer une méthode de contrôleur avec AuthorizeAttribute, comme ceci:

[Authorize(Roles = "CanDeleteTags")]
public void Delete(string tagName)
{
    // ...
}

Cela signifie que, si l'utilisateur actuellement connecté n'est pas dans le "CanDeleteTags" le rôle, la méthode de contrôleur ne sera jamais appelé.

Malheureusement, pour les échecs, AuthorizeAttribute retours HttpUnauthorizedResult, ce qui renvoie toujours le code d'état HTTP 401. Cela provoque une redirection vers la page de connexion.

Si l'utilisateur n'est pas connecté, cela fait beaucoup de sens. Toutefois, si l'utilisateur est déjà connecté, mais n'est pas dans le rôle, c'est source de confusion pour les renvoyer à la page de connexion.

Il semble qu' AuthorizeAttribute débordait d'authentification et d'autorisation.

Cela semble être un peu une surveillance dans ASP.NET MVC, ou ai-je raté quelque chose?

J'ai dû cuire jusqu'à une DemandRoleAttribute qui sépare les deux. Lorsque l'utilisateur n'est pas authentifié, il renvoie une erreur HTTP 401, de les envoyer à la page de connexion. Lorsque l'utilisateur est connecté, mais n'est pas dans le rôle, il crée un NotAuthorizedResult à la place. Actuellement, cette redirige vers une page d'erreur.

Certes, je n'ai pas eu à le faire?

316voto

ShadowChaser Points 2468

Techniquement parlant du Système.Web.Mvc.AuthorizeAttribute est en train de faire la bonne chose -, c'est sans doute une faille que la spécification HTTP utilise 401 pour les deux "non autorisée" et "non authentifié".

À partir de la spécification: "Si la demande déjà inclus Autorisation des informations d'identification, puis la réponse 401 indique que l'autorisation a été refusée pour ces informations d'identification."

En fait, vous pouvez voir la confusion dans la spécification - il utilise le mot "autorisation" quand il signifie "authentification". Dans le quotidien de la pratique, cependant, il est plus logique de renvoyer un 403 Forbidden lorsque l'utilisateur est authentifié, mais pas autorisé. Il est peu probable que l'utilisateur aurait un deuxième ensemble d'informations d'identification qui leur donnerait accès mauvaise expérience utilisateur tout autour.

Considérer la plupart des systèmes d'exploitation - lorsque vous essayez de lire un fichier que vous n'avez pas la permission d'accéder, vous n'êtes pas montré un écran de connexion!

Plutôt que d'essayer de changer ASP.NET s'login page de redirection, il est plus facile de résoudre le problème à la source. Vous pouvez créer un nouvel attribut avec le même nom (AuthorizeAttribute) dans votre site web de l'espace de noms par défaut (ce qui est très important), alors le compilateur détectera automatiquement à la place de la MVC du standard. Bien sûr, vous pouvez toujours donner à l'attribut d'un nouveau nom si vous préférez prendre cette approche.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAuthenticated)
        {
            filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

23voto

Alan Jackson Points 3420

Ajoutez ceci à votre de Connexion Page_Load de la fonction:

// User was redirected here because of authorization section
if (User.Identity != null && User.Identity.IsAuthenticated)
    Response.Redirect("Unauthorized.aspx");

Lorsque l'utilisateur est redirigé là, mais est déjà connecté, il montre la page non autorisée. Si ils ne sont pas connectés, il tombe à travers et affiche la page de connexion.

4voto

Keltex Points 17151

Malheureusement, vous avez à traiter avec le comportement par défaut de ASP.NET l'authentification par formulaires. Il y a une solution (je n'ai pas essayé) discuté ici:

http://www.codeproject.com/KB/aspnet/Custon401Page.aspx

(Ce n'est pas spécifique à la MVC)

Je pense que dans la plupart des cas, la meilleure solution est de limiter l'accès non autorisé aux ressources avant à l'utilisateur d'essayer. En supprimant/grisonnants le lien ou le bouton qui pourrait les prendre à cette page non autorisée.

Il serait sans doute utile d'avoir un paramètre supplémentaire sur l'attribut pour spécifier où rediriger un utilisateur non autorisé. Mais en attendant, je regarde la AuthorizeAttribute comme un filet de sécurité.

4voto

Rob Points 1092

J'ai toujours pensé que cela avait du sens. Si vous êtes connecté et que vous essayez de frapper à une page qui nécessite un rôle que vous n'avez pas, vous obtenez transmis à l'écran de connexion vous demandant de vous connecter avec un utilisateur qui a le rôle.

Vous pouvez ajouter de la logique à la page de connexion qui vérifie si l'utilisateur est déjà authentifié. Vous pouvez ajouter un message amical qui explique pourquoi elles ont été bumbed y retourner de nouveau.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X