in Architettura Software, Informatica

Autenticazione multi JWT in Dotnet Core

Ci si può trovare nella situazione di dover utilizzare piu un autenticazione JWT all’interno di un applicazione .net Core.In particolare, potremmo avere la necessità di autenticare le API in maniera differente (con jwt token differenti).

DotNet Core (nel mio caso ho utilizzato la versione 8.0) ci permette di gestire queste situazioni in maniera piuttosto agevole.

Dopo aver creato un applicazione WebApi, integriamo il progetto con i pacchetti:

    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.1" />
    <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.1" />

in modo da poter utilizzare token bearer e OpenIdConnect.

A questo punto è necessario modificare il Program.cs in modo da poter gestire la validazione multi-token

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer("Name1", options =>
    {
        options.Audience = "AudienceName1";
        options.Authority = "AuthURL1";
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidAudience = $"AudienceName1",
            ValidIssuer = $"AuthURL1",
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes($"KEY"))
        };
    })
    .AddJwtBearer("Name2", options =>
    {
        options.Audience = "AudienceName2";
        options.Authority = "AuthURL2";
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidAudience = $"AUDIENCENAME2",
            ValidIssuer = $"AUTHURL2",
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes($"KEY2"))
        };
    });

Nell’esempio abbiamo aggiunto la possibilità di usare due token differenti, con la relativa validazione. In particolare la validazione è completa: viene verificato l’issuer, l’audience e la relativa chiave. Ovviamente devono essere modificati i valori all’interno delle singole opzioni in base ai servizi che dovranno essere gestiti.

Abbiamo sistemato la parte relativa all’Autenticazione. Dobbiamo passare alla parte Autorizzazione.

Dobbiamo modificare il Program.cs, aggiungendo :

builder.Services.AddAuthorization(options =>
    {
        options.AddPolicy("Name1", new AuthorizationPolicyBuilder()
          .RequireAuthenticatedUser()
          .AddAuthenticationSchemes("Name1")
          .Build());

        options.AddPolicy("Name2", new AuthorizationPolicyBuilder()
          .RequireAuthenticatedUser()
          .AddAuthenticationSchemes("Name2")
          .Build());
    });

creando due policies per l’autenticazione definita in precedenza. In questo modo creiamo due policy chiamate Name1 e Name2 che utilizzano come schema di validazione quello definito nel blocco di codice precedente.

A questo punto è necessario aggiungere l’autenticazione e l’autorizzazione nel modo seguente :

app.UseAuthentication();
app.UseAuthorization();

Lato configurazione è tutto. Per poter utilizzare le nuove policies nei controllers è necessario aggiungere [Authorize] con il nome della policy che dovrà essere utilizzata:

[Authorize("Name1")]

Utilizzando questo approccio è possibile creare e gestire l’autenticazione basata su token differenti, definendo il comportamento per ogni singolo controller/action.

[Authorize("Name1")]