Lecture du AuthorizationFilterContext dans netcore api 3.1

9

J'ai un projet netcore 2.2 fonctionnel où j'ai mis en œuvre une politique personnalisée qui vérifie les clés API.

Dans le startup.cs j'ajoute cette politique comme ceci

//Add Key Policy
services.AddAuthorization(options =>
{
    options.AddPolicy("AppKey", policy => policy.Requirements.Add(new AppKeyRequirement()));
});

Dans mon AppKeyRequirement, j'hérite de AuthorizationHandler et résout les clés dans les demandes entrantes comme ceci

protected override Task HandleRequirementAsync(AuthorizationHandlerContext authContext, AppKeyRequirement requirement)
{
    var authorizationFilterContext = (AuthorizationFilterContext)authContext.Resource;
    var query = authorizationFilterContext.HttpContext.Request.Query;

    if (query.ContainsKey("key") && query.ContainsKey("app"))
    { // Do stuff

Cela ne fonctionne pas dans netcore 3.1

Je reçois l'erreur suivante:

Impossible de convertir un objet de type «Microsoft.AspNetCore.Routing.RouteEndpoint» en type «Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext».

Quelle est la bonne façon de procéder dans le noyau 3 et au-dessus?

Comme l'a souligné Kirk Larkin, la bonne façon dans .net 3.0 et supérieur consiste à injecter IHttpContextAccessor dans le gestionnaire Auth et à l'utiliser.

Ma question à ce stade est de savoir comment injecter cela? Je ne peux pas passer cela dans startup.cs ou au moins je ne vois pas comment.

Toutes les idées / conseils seront très appréciés.

w2olves
la source

Réponses:

14

Dans les versions antérieures à ASP.NET Core 3.0, les implémentations de IAuthorizationHandlerétaient appelées pendant le pipeline MVC. À partir de la version 3.0, qui utilise le routage des points d'extrémité (par défaut), ces implémentations sont appelées par le middleware d'autorisation ( UseAuthorization()). Ce middleware s'exécute avant le pipeline MVC, plutôt que dans le cadre de celui-ci.

Ce changement signifie qu'il AuthorizationFilterContextn'est plus transmis aux gestionnaires d'autorisations. Au lieu de cela, il s'agit d'une instance de RouteEndpoint, qui ne donne pas accès à HttpContext.

Dans votre exemple, vous utilisez uniquement AuthorizationFilterContextpour mettre la main sur HttpContext. Dans 3.0+, injectez IHttpContextAccessordans votre gestionnaire d'autorisation et utilisez-le. Voici un exemple d'exhaustivité:

public class AppKeyAuthorizationHandler : AuthorizationHandler<AppKeyRequirement>
{
    private readonly IHttpContextAccessor httpContextAccessor;

    public AppKeyAuthorizationHandler(IHttpContextAccessor httpContextAccessor)
    {
        this.httpContextAccessor = httpContextAccessor;
    }

    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext authContext, AppKeyRequirement requirement)
    {
        var httpContext = httpContextAccessor.HttpContext;
        var query = httpContext.Request.Query;

        if (query.ContainsKey("key") && query.ContainsKey("app"))
        {
            // ...
        }
    }
}

Vous devrez peut-être également vous inscrire IHttpContextAccessordans ConfigureServices:

services.AddHttpContextAccessor();

Voir Utiliser HttpContext à partir de composants personnalisés pour plus d'informations sur l'utilisation IHttpContextAccessor.

Kirk Larkin
la source
1
Merci pour cet indice. J'essaie de créer une politique selon laquelle s'il manque une clé API, l'appel sera rejeté. Pouvons-nous ne plus utiliser // Add Key Policy services.AddAuthorization (options => {options.AddPolicy ("AppKey", policy => policy.Requirements.Add (new AppKeyRequirement ()));}); Sinon, comment puis-je intercepter un appel avant qu'il ne frappe une action du contrôleur?
w2olves
1
Oui, cela fonctionne toujours comme avant.
Kirk Larkin,
Le constructeur attend IHttpContextAccessor comment puis-je passer cela lorsque je crée la stratégie dans Startup.cs? services.AddAuthorization (options => {options.AddPolicy ("AppKey", policy => policy.Requirements.Add (new AppKeyRequirement ()));}); Je peux également créer un nouveau constructeur par défaut pour AppKeyAuthorizationHandler mais ensuite httpContextAccessor.HttpContext; est nul lorsqu'une demande arrive. Des idées?
w2olves
1
Vous ajoutez votre gestionnaire à l'aide de DI, ce qui crée une instance de celui-ci pour vous et passe dans le IHttpContextAccessor. Voir les documents .
Kirk Larkin,