Lettura di AuthorizationFilterContext in netcore api 3.1


9

Ho un progetto netcore 2.2 funzionante in cui ho implementato una politica personalizzata che controlla le chiavi API.

In startup.cs sto aggiungendo questa politica in questo modo

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

Nel mio AppKeyRequirement eredito da AuthorizationHandler e risolvo le chiavi nelle richieste in arrivo in questo modo

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

Questo non funziona in netcore 3.1

Ricevo il seguente errore:

Impossibile eseguire il cast dell'oggetto di tipo "Microsoft.AspNetCore.Routing.RouteEndpoint" per digitare "Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext".

Qual è il modo corretto per farlo nel core 3 e versioni successive?

Come sottolineato da Kirk Larkin, il modo corretto in .net 3.0 e versioni successive è di iniettare IHttpContextAccessor nel gestore Auth e utilizzarlo.

La mia domanda a questo punto è come posso iniettarlo? Non posso passare questo in startup.cs o almeno non vedo come.

Eventuali idee / suggerimenti saranno molto apprezzati.

Risposte:


14

Nelle versioni precedenti ad ASP.NET Core 3.0, le implementazioni di IAuthorizationHandlererano state chiamate durante la pipeline MVC. A partire da 3.0, che utilizza il routing endpoint (per impostazione predefinita), queste implementazioni vengono chiamate dal middleware di autorizzazione ( UseAuthorization()). Questo middleware viene eseguito prima della pipeline MVC, piuttosto che come parte di esso.

Questa modifica significa che AuthorizationFilterContextnon viene più passato ai gestori di autorizzazioni. Invece, è un'istanza di RouteEndpoint, che non fornisce accesso a HttpContext.

Nel tuo esempio, stai solo usando AuthorizationFilterContextper ottenere HttpContext. In 3.0+, iniettare IHttpContextAccessornel gestore delle autorizzazioni e utilizzarlo. Ecco un esempio di completezza:

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"))
        {
            // ...
        }
    }
}

Potrebbe anche essere necessario registrarsi IHttpContextAccessorin ConfigureServices:

services.AddHttpContextAccessor();

Vedi Usa HttpContext da componenti personalizzati per maggiori informazioni sull'uso IHttpContextAccessor.


1
Grazie per questo suggerimento. Sto cercando di creare una politica in cui se manca una chiave API la chiamata verrà rifiutata. Non possiamo più utilizzare // Aggiungi servizi di criteri chiave.AddAuthorization (options => {options.AddPolicy ("AppKey", policy => policy.Requirements.Add (new AppKeyRequirement ()));}); In caso contrario, come posso intercettare una chiamata prima che colpisca un'azione del controller?
w2olves,

1
Sì, funziona ancora come prima.
Kirk Larkin,

Il costruttore si aspetta IHttpContextAccessor come posso passare questo quando creo la politica in Startup.cs? services.AddAuthorization (options => {options.AddPolicy ("AppKey", policy => policy.Requirements.Add (new AppKeyRequirement ()));}); Posso anche creare un nuovo costruttore predefinito per AppKeyAuthorizationHandler ma poi httpContextAccessor.HttpContext; è nullo quando arriva una richiesta. Qualche idea?
w2olves,

1
Aggiungi il tuo gestore usando DI, che crea un'istanza per te e passa in IHttpContextAccessor. Vedi i documenti .
Kirk Larkin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.