La sicurezza è uno degli aspetti più delicati nello sviluppo di applicazioni moderne. Autenticazione, autorizzazione e gestione sicura delle connessioni a risorse esterne sono elementi indispensabili in qualsiasi architettura cloud native.
Spesso, però, integrare questi aspetti comporta configurazioni complesse: bisogna gestire token, connection string, segreti e certificati. Con .NET Aspire, la sicurezza e l’identity vengono integrate fin dall’inizio nel ciclo di sviluppo, in modo dichiarativo e uniforme.
Vediamo un esempio pratico in cui un progetto API utilizza OpenID Connect per autenticare gli utenti tramite un Identity Provider esterno.
AppHost/Program.cs
var builder = DistributedApplication.CreateBuilder(args);
// Definiamo un Identity Provider esterno (ad es. Azure AD)
var identity = builder.AddHttpApi("auth", "https://login.microsoftonline.com/{tenantId}/v2.0");
builder.AddProject<Projects.MyApi>("api")
.WithReference(identity);
builder.Build().Run();
MyApi/Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication("OpenIdConnect")
.AddOpenIdConnect("OpenIdConnect", options =>
{
options.Authority = builder.Configuration.GetConnectionString("auth");
options.ClientId = "my-client-id";
options.ClientSecret = builder.Configuration["Secrets:ApiSecret"];
options.ResponseType = "code";
});
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy =>
policy.RequireClaim("role", "Admin"));
});
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapGet("/secure", () => "Accesso consentito solo agli admin")
.RequireAuthorization("AdminOnly");
app.Run();
Con questa configurazione, Aspire fornisce all’API l’endpoint dell’Identity Provider e gestisce i segreti in modo sicuro.
Uno degli errori più comuni nello sviluppo è inserire connection string o chiavi API direttamente nel codice o nei file di configurazione. Aspire risolve questo problema introducendo un sistema centralizzato per la gestione dei segreti.
Esempio – aggiunta di un segreto:
dotnet user-secrets set "Secrets:ApiSecret" "super-password-123"
Aspire rende il segreto disponibile al progetto senza che venga esposto nei file sorgente. Questo approccio è compatibile anche con gestori esterni come Azure Key Vault o AWS Secrets Manager.
Oltre all’autenticazione, le applicazioni moderne devono applicare regole granulari di autorizzazione. Aspire supporta le policy-based authorization di ASP.NET Core.
Esempio – API con autorizzazioni differenziate:
app.MapGet("/orders", () => "Lista ordini")
.RequireAuthorization();
app.MapGet("/admin", () => "Area riservata agli admin")
.RequireAuthorization("AdminOnly");
In questo modo, puoi differenziare facilmente l’accesso in base ai ruoli o ai claim.
Aspire si occupa anche di garantire connessioni sicure a database, code di messaggi e API. Le connection string non vengono mai esposte direttamente nel codice: ogni progetto riceve i valori attraverso il sistema di reference.
Esempio – collegamento a PostgreSQL:
var db = builder.AddPostgres("postgres")
.AddDatabase("appdb");
builder.AddProject<Projects.MyApi>("api")
.WithReference(db);
Il progetto API riceverà automaticamente la connection string sicura per appdb.
Aspire semplifica la sicurezza in diversi modi:
In sostanza, Aspire trasforma la sicurezza da un ostacolo tecnico a un componente naturale dell’architettura, riducendo errori e tempi di setup.
Con .NET Aspire, autenticazione, autorizzazione e gestione dei segreti diventano parte integrante dell’applicazione, senza bisogno di configurazioni manuali complesse. Questo non solo accelera lo sviluppo, ma rende le applicazioni più sicure e pronte a essere distribuite in ambienti cloud.
Nel prossimo articolo parleremo di scalabilità e resilienza in .NET Aspire, analizzando come Aspire semplifica il deployment di applicazioni distribuite pronte per carichi variabili e failover.