Disclaimer

Mi è capitato di notare il seguente comportamento su un progetto Web Api (si noti che l’AuthorizationFilter per le web api è diverso da quello per i controller MVC) .NET Framework 4.8. Non ho ancora verificato se lo stesso accade anche con .NET core e successivi, o su progetti MVC.

Inoltre, non ho verificato se il comportamento anomalo si verifica anche nel caso di action filter o exception filter.

Descrizione del comportamento

E’ definito un authorization filter custom, con una property custom (il problema può verificarsi anche con le property predefinite, come riportato qui: https://stackoverflow.com/questions/58491975/custom-authorization-atribute-asp-net-webapi-null-roles. Tuttavia, in quel caso la soluzione è molto più complessa). Tale filtro è applicato, come attributo, ad una action di un controller, impostando contestualmente il valore della property (lo stesso accade comunque in casi più complessi, tipo quando si applica il filtro al controller, sia al controller che alla action, più volte alla stessa action o allo stesso controller, ecc.. Non ho invece verificato il caso in cui si aggiunge il filtro ai filtri globali all’avvio dell’applicazione).

In fase di avvio dell’applicazione il filtro viene istanziato e la property viene settata con il valore corretto. Il problema è che quando si esegue la prima chiamata alla action, viene chiamato nuovamente il set della property, ma con il valore di default per quel tipo (sostanzialmente, viene resettata). Il costruttore invece non viene più invocato dopo l’istanziazione iniziale (non si tratta quindi di una sostituzione del filtro originale con uno nuovo).

Se si chiama nuovamente la stessa action, il set della property non viene più eseguito. Se il filtro si applica a più action (anche a livello di controller, perché in quel caso viene comunque istanziato un filtro diverso per ciascuna action) invece viene nuovamente chiamato il set, ma sempre solo alla prima chiamata.

Analisi

Non sono riuscito a riprodurre il comportamento anomalo con gli unit test, mentre ci sono riuscito con dei test end to end. Anche alla luce del codice della classe base System.Web.Http.AuthorizeAttribute (https://github.com/aspnet/AspNetWebStack/blob/main/src/System.Web.Http/AuthorizeAttribute.cs), ritengo che il problema non risieda nel filtro, ma nel middleware che lo invoca prima dell’esecuzione della action.

Non sono tuttavia riuscito finora ad individuare la causa del problema. Se qualcuno ha qualche idea, mi contatti a info@dvisentin.com.

Workaround

Il workaround che ho adottato consiste nel controllare, nel set della property, che value non sia il valore di default per quel tipo prima di assegnarlo al backing field.