5 votes

La poignée d'autorisation basée sur la politique d'ASP.NET 5 n'est pas appelée

En suivant la documentation ici, j'ai essayé d'implémenter un schéma d'authentification basé sur une politique. http://docs.asp.net/en/latest/security/authorization/policies.html#security-authorization-handler-example

J'ai rencontré un problème avec ma méthode Handle qui n'était pas appelée sur mon AuthorizationHandler personnalisé. (Il n'est pas lancé ici). Il injecte également la dépendance actuellement dans le constructeur.

Voici le code de l'AuthorizationHandler.

using WebAPIApplication.Services;
using Microsoft.AspNet.Authorization;

namespace WebAPIApplication.Auth
{
    public class TokenAuthHandler : AuthorizationHandler<TokenRequirement>, IAuthorizationRequirement
    {
        private IAuthService _authService;

        public TokenAuthHandler(IAuthService authService)
        {
            _authService = authService;
        }

        protected override void Handle(AuthorizationContext context, TokenRequirement requirement)
        {
            throw new Exception("Handle Reached");
        }
    } 

    public class TokenRequirement : IAuthorizationRequirement
    {
        public TokenRequirement()
        {
        }
    }
}

Dans Start Up, j'ai

// Authorization
            services.AddSingleton<IAuthorizationHandler, TokenAuthHandler>()
                .AddAuthorization(options =>
                {
                    options.AddPolicy("ValidToken",
                        policy => policy.Requirements.Add(new TokenRequirement()));
                });

La méthode du contrôleur est la suivante

// GET: api/values
        [HttpGet, Authorize(Policy="ValidToken")]
        public string Get()
        {
            return "test";
        }

L'activation de ce point d'accès ne renvoie rien et la console affiche un message d'avertissement du type

warn: Microsoft.AspNet.Mvc.Controllers.ControllerActionInvoker[0]
      Authorization failed for the request at filter 'Microsoft.AspNet.Mvc.Filters.AuthorizeFilter'.

Je suis en mesure d'atteindre d'autres points de terminaison qui n'ont pas l'attribut avec succès.

SOS, Jack

7voto

Ben Walters Points 329

Je le mets ici à titre de référence parce que j'ai passé beaucoup trop de temps à le découvrir...

J'ai mis en place une exigence et un gestionnaire personnalisés (vides pour les besoins du test) :

using Microsoft.AspNetCore.Authorization;
using System.Threading.Tasks;

public class TestHandler : AuthorizationHandler<TestRequirement>, IAuthorizationRequirement
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TestRequirement requirement)
    {
        context.Succeed(requirement);
        return Task.CompletedTask;
    }
}

public class TestRequirement : IAuthorizationRequirement
{

}

Je l'ai enregistré dans mon Startup.cs ConfigureServices() section :

services.AddAuthorization(options =>
{
    options.AddPolicy("Test", policy => policy.Requirements.Add(new TestRequirement()));
    // Other policies here
}

Je l'ai ajouté à ma méthode de contrôle :

[HttpGet]
[Authorize(Policy = "Test")]
public IActionResult Index()
{
    Return View();
}

Mais j'obtenais une erreur 403 (et non 401) à chaque requête vers la méthode du contrôleur !

Il s'avère que je n'étais pas en train de m'inscrire TestHandler avec le ConfigureServices() (Injection de dépendance) de la section Startup.cs .

services.AddSingleton<IAuthorizationHandler, TestHandler>();

J'espère que cela évitera à quelqu'un de se cogner la tête sur son bureau :|

3voto

Hamburglar Points 420

La réponse à cette question se trouve dans un commentaire d'adem caglin, donc bravo à lui.

Le problème est que la AuthorizeFilter rejette la demande avant que le AuthorizationHandler est appelé. En effet, pour chaque utilisation de la fonction Authorize La balise MVC ajoute AuthorizeFilter en amont de la AuthorizationHandler en cours d'élaboration. Ce projet AuthorizeFilter vérifie si l'une des identités des utilisateurs actuels est autorisée. Dans mon cas, il n'y avait pas d'identités autorisées associées à un utilisateur, donc cela échouait toujours.

Une solution (qui est quelque peu hackish) est d'insérer un middleware qui sera exécuté avant n'importe quel code MVC. Ce middleware ajoutera une identité générique authentifiée à un utilisateur (si l'utilisateur n'en a pas déjà une).

Par conséquent, le AuthorizeFilter passera et le Handle sur la méthode AuthenticationHandler sera exécutée et notre problème sera résolu. Le code de l'intergiciel (qui doit être ajouté à Configure antes de app.UseMvc(); est appelé) est le suivant

    app.Use(async (context, next) =>
    {
        if (!context.User.Identities.Any(i => i.IsAuthenticated))
        {
            context.User = new ClaimsPrincipal(new GenericIdentity("Unknown"));
        }
        await next.Invoke();
    });

Une autre façon de remplacer la fonction AuthorizeFilter est décrite ici ( Remplacer le filtre d'autorisation global dans ASP.NET Core MVC 1.0 )

Citant la réponse d'ici ( L'autorisation basée sur la politique d'Asp.Net Core se termine par 401 Non autorisé )

1voto

adem caglin Points 9337

Jetez un coup d'œil à Asp.net Core Authorize Redirection ne se produit pas Je pense que l'ajout de options.AutomaticChallenge = true; résout votre problème.

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