Come sappiamo, tramite il pacchetto NuGet Swashbuckle, possiamo generare automaticamente lo swagger document di un progetto ASP.NET Core Web API e dotare la nostra applicazione di una pagina web che illustri tutti gli endpoint esposti.
Un aspetto importante di cui tenere conto è che sia la pagina, sia il documento swagger, sono pubblicamente disponibili, a prescindere dal fatto che la nostra Web API sia invece magari protetta da OAuth. In alcuni contesti, questo potrebbe non essere accettabile, richiedendoci quindi di proteggere dietro autenticazione queste pagine.
L'autenticazione basata su OAuth non è indicata per questo tipo di necessità, visto che richiederebbe un token JWT come header della richiesta della pagina web. Ciò che vogliamo invece è utilizzare OpenID Connect, così che venga effettuato un redirect verso l'Identity Provider (per esempio Azure Active Directory).
Il primo passo allora è quello di configurare, oltre al protocollo OAuth, anche l'autenticazione OpenID Connect, all'interno del metodo ConfigureServices della classe Startup:
public void ConfigureServices(IServiceCollection services) { // questa configurazione è usata per proteggere Web API services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme) .AddAzureADBearer(options => Configuration.Bind("AzureAd", options)); // questo configurazione è usata per proteggere la pagina Swagger services.AddAuthentication() .AddOpenIdConnect(options => { options.ClientId = "[clientID dell'applicazione]"; options.Authority = $"https://login.microsoftonline.com/[tenantId]"; options.UseTokenLifetime = true; options.CallbackPath = "/signin-oidc"; options.RequireHttpsMetadata = false; options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.SignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme; }) .AddCookie(); // altro codice qui
Come possiamo notare dal codice in alto, la nostra applicazione usufruirà di tre sistemi di autenticazione differenti:
- JwtBearer è il provider per OAuth, ed è configurato come default. Questo vuol dire che ogni controller dotato dell'attributo Authorize, utilizzerà questo provider per procedere all'autenticazione dell'utente;
- il provider OpenIDConnect sfrutta nel nostro caso il medesimo client ID su Azure Active Directory e verrà attivato solo all'occorrenza, con una tecnica che vedremo più in basso;
- OpenIDConnect non è autosufficiente, e necessita di un ulteriore provider tramite cui memorizzare l'esito dell'autenticazione. Per questo motivo abbiamo aggiunto anche la Cookie authentication, che abbiamo referenziato come SignInScheme e SignOutScheme.
A questo punto siamo pronti per utilizzare la nostra autenticazione secondaria, registrando un nuovo middleware tramite il metodo app.Use all'interno di Configure:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // .. altro codice qui .. app.Use(async (ctx, next) => { if (ctx.Request.Path.ToString().Contains("swagger")) { var result = await ctx.AuthenticateAsync( CookieAuthenticationDefaults.AuthenticationScheme); if (!result.Succeeded) { await ctx.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme); return; } } await next(); }); app.UseSwagger(); app.UseSwaggerUI(...); // .. altro codice qui .. }
La logica di questo middleware si attiva solo quando l'URL contiene la parola "swagger" e prova inizialmente ad autenticare l'utente tramite Cookie. Il metodo AuthenticateAsync ritornerà un risultato Succeded se l'utente ha già effettuato il login in precedenza e memorizzato l'esito in un cookie. In caso contrario, il passo successivo è quello di invocare l'autenticazione OpenID Connect che effettuerà il redirect verso l'identity provider, richiedendo quindi username e password all'utente.
Un'ultima nota è relativa al fatto che dobbiamo ovviamente registrare questo middleware prima di Swagger e SwaggerUI, così che il controllo sull'autenticazione preceda il rendering della pagina o del Json di Swagger.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Estrarre dati randomici da una lista di oggetti in C#
Generare file PDF da Blazor WebAssembly con iText
Effettuare chiamate con versioning da Blazor ad ASP.NET Core
Verificare la provenienza di un commit tramite le GitHub Actions
Sviluppare un'interfaccia utente in React con Tailwind CSS e Preline UI
Implementare il throttling in ASP.NET Core
Come migrare da una form non tipizzata a una form tipizzata in Angular
Eseguire un metodo asincrono dopo il set di una proprietà in Blazor 8
.NET Conference Italia 2023
Semplificare il deployment di siti statici con Azure Static Web App
Evitare (o ridurre) il repo-jacking sulle GitHub Actions
Registrare servizi multipli tramite chiavi in ASP.NET Core 8
I più letti di oggi
- Utilizzare DPAPI: cifrare dati sensibili
- Recuperare la foto dell'utente nelle Windows Store app
- What's new in Azure Functions and Extensions
- dal tuo PC o smartphone tra poco #aspilive: https://aspit.co/VS2015-live tutto su #vs2015, #windows10, #aspnet5 e altro ancora!
- Creare link alle risorse di DocumentDB con UriFactory
- Ottenere il nome esteso del mese
- Eventi personalizzati per l'HealhMonitoring di ASP.NET 2.0
- Utilizare la libreria subsink per eliminare le sottoscrizioni agli observable in Angular
- Ritardata l'uscita di BizTalk Server 2004
- Creare file di Excel al volo