Quindi, dopo una lunga giornata passata a cercare di risolvere questo problema, ho finalmente capito come Microsoft vuole che creiamo gestori di autenticazione personalizzati per la loro nuova configurazione single-middleware nel core 2.0.
Dopo aver esaminato parte della documentazione su MSDN, ho trovato una classe chiamata AuthenticationHandler<TOption>
che implementa l' IAuthenticationHandler
interfaccia.
Da lì, ho trovato un'intera base di codice con gli schemi di autenticazione esistenti situati su https://github.com/aspnet/Security
All'interno di uno di questi, mostra come Microsoft implementa lo schema di autenticazione JwtBearer. ( https://github.com/aspnet/Security/tree/master/src/Microsoft.AspNetCore.Authentication.JwtBearer )
Ho copiato la maggior parte di quel codice in una nuova cartella e ho cancellato tutte le cose che avevano a che fare con JwtBearer
.
Nella JwtBearerHandler
classe (che si estende AuthenticationHandler<>
), c'è un override perTask<AuthenticateResult> HandleAuthenticateAsync()
Ho aggiunto il nostro vecchio middleware per l'impostazione delle attestazioni tramite un server token personalizzato e riscontravo ancora alcuni problemi con le autorizzazioni, emettendo semplicemente un 200 OK
invece di un 401 Unauthorized
quando un token non era valido e non erano state configurate rivendicazioni.
Mi sono reso conto che avevo sovrascritto Task HandleChallengeAsync(AuthenticationProperties properties)
che per qualsiasi motivo viene utilizzato per impostare le autorizzazioni tramite [Authorize(Roles="")]
un controller.
Dopo aver rimosso questo override, il codice aveva funzionato e aveva generato con successo un messaggio di errore 401
quando le autorizzazioni non corrispondevano.
Il punto principale è che ora non puoi usare un middleware personalizzato, devi implementarlo tramite AuthenticationHandler<>
e devi impostare DefaultAuthenticateScheme
e DefaultChallengeScheme
quando lo usi services.AddAuthentication(...)
.
Ecco un esempio di come dovrebbe apparire tutto questo:
In Startup.cs / ConfigureServices () aggiungere:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = "Custom Scheme";
options.DefaultChallengeScheme = "Custom Scheme";
})
.AddCustomAuth(o => { });
In Startup.cs / Configure () aggiungere:
app.UseAuthentication();
Crea un nuovo file CustomAuthExtensions.cs
public static class CustomAuthExtensions
{
public static AuthenticationBuilder AddCustomAuth(this AuthenticationBuilder builder, Action<CustomAuthOptions> configureOptions)
{
return builder.AddScheme<CustomAuthOptions, CustomAuthHandler>("Custom Scheme", "Custom Auth", configureOptions);
}
}
Crea un nuovo file CustomAuthOptions.cs
public class CustomAuthOptions: AuthenticationSchemeOptions
{
public CustomAuthOptions()
{
}
}
Crea un nuovo file CustomAuthHandler.cs
internal class CustomAuthHandler : AuthenticationHandler<CustomAuthOptions>
{
public CustomAuthHandler(IOptionsMonitor<CustomAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
{
}
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
return AuthenticateResult.NoResult();
}
}