Eventi
19 nov, 23 - 21 nov, 23
Partecipa alle sessioni online di Microsoft Ignite create per espandere le tue competenze e aiutarti a risolvere i problemi complessi di oggi.
Iscriviti subitoQuesto browser non è più supportato.
Esegui l'aggiornamento a Microsoft Edge per sfruttare i vantaggi di funzionalità più recenti, aggiornamenti della sicurezza e supporto tecnico.
Nota
Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 9 di questo articolo.
Avviso
Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere i criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 9 di questo articolo.
Importante
Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Per la versione corrente, vedere la versione .NET 9 di questo articolo.
ASP.NET Core Identity fornisce API che gestiscono l'autenticazione, l'autorizzazione e identity la gestione. Le API consentono di proteggere gli endpoint di un back-end dell'API Web con cookiel'autenticazione basata su . Un'opzione basata su token è disponibile per i client che non possono usare i cookie, ma in questo modo si è responsabili della sicurezza dei token. È consigliabile usare i cookie per le applicazioni basate su browser, perché, per impostazione predefinita, il browser li gestisce automaticamente senza esporli a JavaScript.
Questo articolo illustra come usare Identity per proteggere un back-end dell'API Web per le app spA, ad esempio Angular, React e Vue. Le stesse API back-end possono essere usate per proteggere Blazor WebAssembly le app.
I passaggi illustrati in questo articolo aggiungono l'autenticazione e l'autorizzazione a un'app api Web core di ASP.NET che:
net8.0
o versioni successive.Alcune delle istruzioni di test in questo articolo usano l'interfaccia utente di Swagger inclusa nel modello di progetto. L'interfaccia utente di Swagger non è necessaria per l'uso Identity con un back-end dell'API Web.
Installare i pacchetti NuGet seguenti:
Microsoft.AspNetCore.Identity.EntityFrameworkCore
- Consente di Identity usare Entity Framework Core (EF Core).Per iniziare più rapidamente, usare il database in memoria.
Modificare il database in un secondo momento in SQLite o SQL Server per salvare i dati utente tra sessioni durante i test o per l'uso in produzione. Ciò introduce una certa complessità rispetto alla memoria, perché richiede che il database venga creato tramite migrazioni, come illustrato nell'esercitazione EF Coreintroduttiva.
Installare questi pacchetti usando gestione pacchetti NuGet in Visual Studio o il comando dotnet add package CLI.
Aggiungere una classe denominata ApplicationDbContext
che eredita da IdentityDbContext<TUser>:
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
public class ApplicationDbContext : IdentityDbContext<IdentityUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) :
base(options)
{ }
}
Il codice illustrato fornisce un costruttore speciale che consente di configurare il database per ambienti diversi.
Aggiungere una o più delle direttive seguenti using
in base alle esigenze quando si aggiunge il codice illustrato in questi passaggi.
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
Come indicato in precedenza, il modo più semplice per iniziare consiste nell'usare il database in memoria. Ogni esecuzione in memoria inizia con un nuovo database e non è necessario usare le migrazioni. Dopo la chiamata a WebApplication.CreateBuilder(args)
, aggiungere il codice seguente per configurare Identity per l'uso di un database in memoria:
builder.Services.AddDbContext<ApplicationDbContext>(
options => options.UseInMemoryDatabase("AppDb"));
Per salvare i dati utente tra sessioni durante i test o per l'uso in produzione, modificare il database in un secondo momento in SQLite o SQL Server.
Dopo la chiamata a WebApplication.CreateBuilder(args)
, chiamare AddAuthorization per aggiungere servizi al contenitore di inserimento delle dipendenze:
builder.Services.AddAuthorization();
Dopo la chiamata a WebApplication.CreateBuilder(args)
, chiamare AddIdentityApiEndpoints<TUser>(IServiceCollection) e AddEntityFrameworkStores<TContext>(IdentityBuilder).
builder.Services.AddIdentityApiEndpoints<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
Per impostazione predefinita, vengono attivati sia i cookie che i token proprietari. I cookie e i token vengono emessi all'account di accesso se il parametro della useCookies
stringa di query nell'endpoint di accesso è true
.
Dopo la chiamata a builder.Build()
, chiamare MapIdentityApi<TUser>(IEndpointRouteBuilder) per eseguire il mapping degli Identity endpoint:
app.MapIdentityApi<IdentityUser>();
Per proteggere un endpoint, usare il RequireAuthorization metodo di estensione nella Map{Method}
chiamata che definisce la route. Ad esempio:
app.MapGet("/weatherforecast", (HttpContext httpContext) =>
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = summaries[Random.Shared.Next(summaries.Length)]
})
.ToArray();
return forecast;
})
.WithName("GetWeatherForecast")
.WithOpenApi()
.RequireAuthorization();
Il RequireAuthorization
metodo può essere usato anche per:
Proteggere gli endpoint dell'interfaccia utente di Swagger, come illustrato nell'esempio seguente:
app.MapSwagger().RequireAuthorization();
Proteggere con un'attestazione o un'autorizzazione specifica, come illustrato nell'esempio seguente:
.RequireAuthorization("Admin");
In un progetto api Web basato su controller, gli endpoint sicuri applicando l'attributo [Authorize
] a un controller o a un'azione.
Un modo rapido per testare l'autenticazione consiste nell'usare il database in memoria e l'interfaccia utente di Swagger inclusa nel modello di progetto. I passaggi seguenti illustrano come testare l'API con l'interfaccia utente di Swagger. Assicurarsi che gli endpoint dell'interfaccia utente di Swagger non siano protetti.
/weatherforecast
in un progetto creato dal modello api Web.401 - not authorized
.Espandere /register
e selezionare Prova.
Nella sezione Parametri dell'interfaccia utente viene visualizzato un corpo della richiesta di esempio:
{
"email": "string",
"password": "string"
}
Sostituire "string" con un indirizzo di posta elettronica e una password validi e quindi selezionare Esegui.
Per rispettare le regole di convalida della password predefinite, la password deve avere una lunghezza di almeno sei caratteri e contenere almeno uno dei caratteri seguenti:
Se si immette un indirizzo di posta elettronica non valido o una password non valida, il risultato include gli errori di convalida. Ecco un esempio di corpo della risposta con errori di convalida:
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"errors": {
"PasswordTooShort": [
"Passwords must be at least 6 characters."
],
"PasswordRequiresNonAlphanumeric": [
"Passwords must have at least one non alphanumeric character."
],
"PasswordRequiresDigit": [
"Passwords must have at least one digit ('0'-'9')."
],
"PasswordRequiresLower": [
"Passwords must have at least one lowercase ('a'-'z')."
]
}
}
Gli errori vengono restituiti nel formato ProblemDetails in modo che il client possa analizzarli e visualizzare gli errori di convalida in base alle esigenze.
Una registrazione riuscita restituisce una 200 - OK
risposta.
Espandere /login
e selezionare Prova. Il corpo della richiesta di esempio mostra due parametri aggiuntivi:
{
"email": "string",
"password": "string",
"twoFactorCode": "string",
"twoFactorRecoveryCode": "string"
}
Le proprietà JSON aggiuntive non sono necessarie per questo esempio e possono essere eliminate. Impostare useCookies
su true
.
Sostituire "string" con l'indirizzo di posta elettronica e la password usati per la registrazione e quindi selezionare Esegui.
Un account di accesso riuscito restituisce una 200 - OK
risposta con un cookie nell'intestazione della risposta.
Dopo aver completato l'accesso, eseguire di nuovo l'endpoint protetto. L'autenticazione cookie viene inviata automaticamente con la richiesta e l'endpoint è autorizzato. CookieL'autenticazione basata su è integrata in modo sicuro nel browser e "funziona".
Alcuni client Web potrebbero non includere cookie nell'intestazione per impostazione predefinita:
Se si usa uno strumento per testare le API, potrebbe essere necessario abilitare i cookie nelle impostazioni.
L'API JavaScript fetch
non include cookie per impostazione predefinita. Abilitarli impostando credentials
sul valore include
nelle opzioni.
Un HttpClient
oggetto in esecuzione in un'app Blazor WebAssembly deve HttpRequestMessage
includere le credenziali, come nell'esempio seguente:
request.SetBrowserRequestCredential(BrowserRequestCredentials.Include);
È consigliabile usare i cookie nelle applicazioni basate su browser, perché, per impostazione predefinita, il browser li gestisce automaticamente senza esporli a JavaScript.
Viene generato un token personalizzato (proprietario della piattaforma ASP.NET Core identity ) che può essere usato per autenticare le richieste successive. Il token viene passato nell'intestazione Authorization
come token di connessione. Viene fornito anche un token di aggiornamento. Questo token consente all'applicazione di richiedere un nuovo token alla scadenza di quella precedente senza forzare l'accesso dell'utente.
I token non sono token Web JSON standard (JWT). L'uso di token personalizzati è intenzionale, perché l'API predefinita Identity è destinata principalmente a scenari semplici. L'opzione token non è progettata per essere un provider di servizi o un server di token completo identity , ma un'alternativa all'opzione cookie per i client che non possono usare i cookie.
Per usare l'autenticazione basata su token, impostare il parametro della useCookies
stringa di query su false
quando si chiama l'endpoint /login
. I token usano lo schema di autenticazione di connessione . Usando il token restituito dalla chiamata a /login
, le chiamate successive agli endpoint protetti devono aggiungere l'intestazione Authorization: Bearer <token>
dove <token>
è il token di accesso. Per altre informazioni, vedere Usare l'endpoint POST /login
più avanti in questo articolo.
Per consentire all'utente di disconnettersi, definire un /logout
endpoint come nell'esempio seguente:
app.MapPost("/logout", async (SignInManager<IdentityUser> signInManager,
[FromBody] object empty) =>
{
if (empty != null)
{
await signInManager.SignOutAsync();
return Results.Ok();
}
return Results.Unauthorized();
})
.WithOpenApi()
.RequireAuthorization();
Specificare un oggetto JSON vuoto ({}
) nel corpo della richiesta quando si chiama questo endpoint. Il codice seguente è un esempio di chiamata all'endpoint di disconnessione:
public signOut() {
return this.http.post('/logout', {}, {
withCredentials: true,
observe: 'response',
responseType: 'text'
La chiamata a MapIdentityApi<TUser>
aggiunge gli endpoint seguenti all'app:
POST /register
POST /login
POST /refresh
GET /confirmEmail
POST /resendConfirmationEmail
POST /forgotPassword
POST /resetPassword
POST /manage/2fa
GET /manage/info
POST /manage/info
Il corpo della richiesta deve avere Email proprietà e Password :
{
"email": "string",
"password": "string",
}
Per altre informazioni, vedi:
Nel corpo Email della richiesta e Password sono necessari. Se l'autenticazione a due fattori (2FA) è abilitata, TwoFactorCode o TwoFactorRecoveryCode è necessaria. Se 2FA non è abilitato, omettere sia twoFactorCode
che twoFactorRecoveryCode
. Per altre informazioni, vedere Usare l'endpoint POST /manage/2fa
più avanti in questo articolo.
Ecco un esempio di corpo della richiesta con 2FA non abilitato:
{
"email": "string",
"password": "string"
}
Ecco alcuni esempi di corpo della richiesta con 2FA abilitato:
{
"email": "string",
"password": "string",
"twoFactorCode": "string",
}
{
"email": "string",
"password": "string",
"twoFactorRecoveryCode": "string"
}
L'endpoint prevede un parametro della stringa di query:
useCookies
- Impostare su true
per cookiel'autenticazione basata su . Impostare su o omettere false
per l'autenticazione basata su token.Per altre informazioni sull'autenticazione cookiebasata su , vedere Testare l'accesso in precedenza in questo articolo.
Se useCookies
viene false
omesso, l'autenticazione basata su token è abilitata. Il corpo della risposta include le proprietà seguenti:
{
"tokenType": "string",
"accessToken": "string",
"expiresIn": 0,
"refreshToken": "string"
}
Per altre informazioni su queste proprietà, vedere AccessTokenResponse.
Inserire il token di accesso in un'intestazione per effettuare richieste autenticate, come illustrato nell'esempio seguente
Authorization: Bearer {access token}
Quando il token di accesso sta per scadere, chiamare l'endpoint /refresh .
Per l'uso solo con l'autenticazione basata su token. Ottiene un nuovo token di accesso senza forzare l'accesso dell'utente. Chiamare questo endpoint quando il token di accesso sta per scadere.
Il corpo della richiesta contiene solo .RefreshToken Ecco un esempio di corpo della richiesta:
{
"refreshToken": "string"
}
Se la chiamata ha esito positivo, il corpo della risposta è un nuovo AccessTokenResponse, come illustrato nell'esempio seguente:
{
"tokenType": "string",
"accessToken": "string",
"expiresIn": 0,
"refreshToken": "string"
}
Se Identity è configurata per la conferma tramite posta elettronica, una chiamata all'endpoint /register
invia un messaggio di posta elettronica contenente un collegamento all'endpoint /confirmEmail
. Il collegamento contiene i parametri della stringa di query seguenti:
userId
code
changedEmail
- Incluso solo se l'utente ha modificato l'indirizzo di posta elettronica durante la registrazione.Identity fornisce il testo predefinito per il messaggio di posta elettronica di conferma. Per impostazione predefinita, l'oggetto del messaggio di posta elettronica è "Conferma il messaggio di posta elettronica" e il corpo del messaggio di posta elettronica è simile all'esempio seguente:
Please confirm your account by <a href='https://contoso.com/confirmEmail?userId={user ID}&code={generated code}&changedEmail={new email address}'>clicking here</a>.
Se la RequireConfirmedEmail proprietà è impostata su true
, l'utente non può accedere finché l'indirizzo di posta elettronica non viene confermato facendo clic sul collegamento nel messaggio di posta elettronica. Endpoint /confirmEmail
:
Per configurare Identity la conferma tramite posta elettronica, aggiungere il codice in Program.cs
per impostare RequireConfirmedEmail
true
e aggiungere una classe che implementa al contenitore di inserimento delle dipendenze IEmailSender . Ad esempio:
builder.Services.Configure<IdentityOptions>(options =>
{
options.SignIn.RequireConfirmedEmail = true;
});
builder.Services.AddTransient<IEmailSender, EmailSender>();
Per altre informazioni, vedere Conferma dell'account e ripristino della password in ASP.NET Core.
Identity fornisce testo predefinito per gli altri messaggi di posta elettronica che devono essere inviati, ad esempio per 2FA e reimpostazione della password. Per personalizzare questi messaggi di posta elettronica, fornire un'implementazione personalizzata dell'interfaccia IEmailSender
. Nell'esempio precedente è EmailSender
una classe che implementa IEmailSender
. Per altre informazioni, incluso un esempio di classe che implementa IEmailSender
, vedere Conferma dell'account e ripristino della password in ASP.NET Core.
Invia un messaggio di posta elettronica solo se l'indirizzo è valido per un utente registrato.
Il corpo della richiesta contiene solo .Email Ecco un esempio di corpo della richiesta:
{
"email": "string"
}
Per altre informazioni, vedere Usare l'endpoint GET /confirmEmail
in precedenza in questo articolo.
Genera un messaggio di posta elettronica contenente un codice di reimpostazione della password. Inviare il codice a /resetPassword
con una nuova password.
Il corpo della richiesta contiene solo .Email Ecco un esempio:
{
"email": "string"
}
Per informazioni su come abilitare Identity l'invio di messaggi di posta elettronica, vedere Usare l'endpointGET /confirmEmail
.
Chiamare questo endpoint dopo aver ottenuto un codice di reimpostazione chiamando l'endpoint /forgotPassword
.
Il corpo della richiesta richiede Email, ResetCodee NewPassword. Ecco un esempio:
{
"email": "string",
"resetCode": "string",
"newPassword": "string"
}
Configura l'autenticazione a due fattori (2FA) per l'utente. Quando la funzionalità 2FA è abilitata, l'accesso con esito positivo richiede un codice prodotto da un'app di autenticazione oltre all'indirizzo di posta elettronica e alla password.
Per abilitare 2FA per l'utente attualmente autenticato:
Chiamare l'endpoint /manage/2fa
, inviando un oggetto JSON vuoto ({}
) nel corpo della richiesta.
Il corpo della SharedKey risposta fornisce insieme ad altre proprietà che non sono necessarie a questo punto. La chiave condivisa viene usata per configurare l'app di autenticazione. Esempio di corpo della risposta:
{
"sharedKey": "string",
"recoveryCodesLeft": 0,
"recoveryCodes": null,
"isTwoFactorEnabled": false,
"isMachineRemembered": false
}
Usare la chiave condivisa per ottenere una password monouso basata sul tempo (TOTP). Per altre informazioni, vedere Abilitare la generazione di codice a matrice per le app di autenticazione TOTP in ASP.NET Core.
Chiamare l'endpoint /manage/2fa
, inviando TOTP e "enable": true
nel corpo della richiesta. Ad esempio:
{
"enable": true,
"twoFactorCode": "string"
}
Il corpo della risposta conferma che IsTwoFactorEnabled è true e fornisce .RecoveryCodes I codici di ripristino vengono usati per accedere quando l'app di autenticazione non è disponibile. Esempio di corpo della risposta dopo aver abilitato correttamente 2FA:
{
"sharedKey": "string",
"recoveryCodesLeft": 10,
"recoveryCodes": [
"string",
"string",
"string",
"string",
"string",
"string",
"string",
"string",
"string",
"string"
],
"isTwoFactorEnabled": true,
"isMachineRemembered": false
}
Chiamare l'endpoint, inviare l'indirizzo /login
di posta elettronica, la password e TOTP nel corpo della richiesta. Ad esempio:
{
"email": "string",
"password": "string",
"twoFactorCode": "string"
}
Se l'utente non ha accesso all'app di autenticazione, accedere chiamando l'endpoint /login
con uno dei codici di ripristino forniti quando è stata abilitata la funzionalità 2FA. Il corpo della richiesta è simile all'esempio seguente:
{
"email": "string",
"password": "string",
"twoFactorRecoveryCode": "string"
}
Per ottenere una nuova raccolta di codici di ripristino, chiamare questo endpoint con ResetRecoveryCodes impostato su true
. Ecco un esempio di corpo della richiesta:
{
"resetRecoveryCodes": true
}
Per ottenere una nuova chiave condivisa casuale, chiamare questo endpoint con ResetSharedKey impostato su true
. Ecco un esempio di corpo della richiesta:
{
"resetSharedKey": true
}
La reimpostazione della chiave disabilita automaticamente il requisito di accesso a due fattori per l'utente autenticato fino a quando non viene riabilitato da una richiesta successiva.
Per cancellare il cookie flag "ricordami" se presente, chiamare questo endpoint con ForgetMachine impostato su true. Ecco un esempio di corpo della richiesta:
{
"forgetMachine": true
}
Questo endpoint non ha alcun impatto sull'autenticazione basata su token.
Ottiene l'indirizzo di posta elettronica e lo stato di conferma tramite posta elettronica dell'utente connesso. Le attestazioni sono state omesse da questo endpoint per motivi di sicurezza. Se sono necessarie attestazioni, usare le API lato server per configurare un endpoint per le attestazioni. In alternativa, invece di condividere tutte le attestazioni degli utenti, fornire un endpoint di convalida che accetta un'attestazione e risponde se l'utente lo ha.
La richiesta non richiede parametri. Il corpo della risposta include le Email proprietà e IsEmailConfirmed , come nell'esempio seguente:
{
"email": "string",
"isEmailConfirmed": true
}
Aggiorna l'indirizzo di posta elettronica e la password dell'utente connesso. Inviare NewEmail, NewPassworde OldPassword nel corpo della richiesta, come illustrato nell'esempio seguente:
{
"newEmail": "string",
"newPassword": "string",
"oldPassword": "string"
}
Ecco un esempio del corpo della risposta:
{
"email": "string",
"isEmailConfirmed": false
}
Per ulteriori informazioni, vedi le seguenti risorse:
useCookies
I modelli di base ASP.NET offrono l'autenticazione in App a pagina singola usando il supporto per l'autorizzazione api. ASP.NET Core Identity per l'autenticazione e l'archiviazione degli utenti viene combinato con Duende Identity Server per l'implementazione di OpenID Connect.
Importante
Duende Software potrebbe richiedere il pagamento di una tariffa di licenza per l'uso in produzione di Duende Identity Server. Per altre informazioni, vedere Eseguire la migrazione da ASP.NET Core 5.0 a 6.0.
È stato aggiunto un parametro di autenticazione ai modelli di progetto Angular e React simili al parametro di autenticazione nei modelli di progetto Applicazione Web (Model-View-Controller) e Applicazione Web (Razor Pages). I valori dei parametri consentiti sono None e Individual. Il modello di progetto React ejs Redux non supporta attualmente il parametro di autenticazione.
L'autenticazione e l'autorizzazione dell'utente possono essere usate sia con Angular che con i criteri di servizio React. Aprire una shell dei comandi ed eseguire il comando seguente:
Angular:
dotnet new angular -au Individual
React:
dotnet new react -au Individual
Il comando precedente crea un'app ASP.NET Core con una directory ClientApp contenente l'applicazione a pagina singola.
Le sezioni seguenti descrivono le aggiunte al progetto quando è incluso il supporto per l'autenticazione:
Gli esempi di codice seguenti si basano sul pacchetto NuGet Microsoft.AspNetCore.ApiAuthorization.IdentityServer . Gli esempi configurano l'autenticazione e l'autorizzazione api usando i AddApiAuthorization metodi di estensione e AddIdentityServerJwt . I progetti che usano i modelli di progetto React o Angular SPA con l'autenticazione includono un riferimento a questo pacchetto.
dotnet new angular -au Individual
genera il file seguente Program.cs
:
using Microsoft.AspNetCore.Authentication;
using Microsoft.EntityFrameworkCore;
using output_directory_name.Data;
using output_directory_name.Models;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
builder.Services.AddAuthentication()
.AddIdentityServerJwt();
builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
app.MapRazorPages();
app.MapFallbackToFile("index.html");
app.Run();
Il codice precedente configura:
Identity con l'interfaccia utente predefinita:
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
IdentityServer con un metodo helper aggiuntivo AddApiAuthorization
che configura alcune convenzioni predefinite ASP.NET Core su IdentityServer:
builder.Services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
Autenticazione con un metodo helper aggiuntivo AddIdentityServerJwt
che configura l'app per convalidare i token JWT prodotti da IdentityServer:
builder.Services.AddAuthentication()
.AddIdentityServerJwt();
Middleware di autenticazione responsabile della convalida delle credenziali della richiesta e dell'impostazione dell'utente nel contesto della richiesta:
app.UseAuthentication();
Middleware IdentityServer che espone gli endpoint OpenID Connect:
app.UseIdentityServer();
Avviso
Questo articolo illustra l'uso di stringa di connessione. Con un database locale l'utente non deve essere autenticato, ma nell'ambiente di produzione stringa di connessione talvolta include una password per l'autenticazione. Una credenziale della password del proprietario della risorsa (ROPC) è un rischio per la sicurezza che deve essere evitato nei database di produzione. Le app di produzione devono usare il flusso di autenticazione più sicuro disponibile. Per altre informazioni sull'autenticazione per le app distribuite in ambienti di test o di produzione, vedere Proteggere i flussi di autenticazione.
Per le distribuzioni del servizio app Azure in Linux, specificare l'autorità di certificazione in modo esplicito:
builder.Services.Configure<JwtBearerOptions>(
IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
options.Authority = "{AUTHORITY}";
});
Nel codice precedente, il {AUTHORITY}
segnaposto è l'oggetto Authority da usare quando si effettuano chiamate OpenID Connect.
Esempio:
options.Authority = "https://contoso-service.azurewebsites.net";
Questo metodo helper configura IdentityServer per l'uso della configurazione supportata. IdentityServer è un framework potente ed estendibile per la gestione dei problemi di sicurezza delle app. Allo stesso tempo, che espone complessità non necessarie per gli scenari più comuni. Di conseguenza, viene fornito un set di convenzioni e opzioni di configurazione che sono considerate un buon punto di partenza. Una volta modificata l'autenticazione, la potenza completa di IdentityServer è ancora disponibile per personalizzare l'autenticazione in base alle proprie esigenze.
Questo metodo helper configura uno schema di criteri per l'app come gestore di autenticazione predefinito. Il criterio è configurato per consentire la Identity gestione di tutte le richieste indirizzate a qualsiasi sottopercorso nello Identity spazio URL "/Identity". JwtBearerHandler
Gestisce tutte le altre richieste. Inoltre, questo metodo registra una <<ApplicationName>>API
risorsa API con IdentityServer con un ambito predefinito e <<ApplicationName>>API
configura il middleware del token di connessione JWT per convalidare i token rilasciati da IdentityServer per l'app.
Nel file osservare l'attributo [Authorize]
applicato alla classe che indica che l'utente deve essere autorizzato in base ai criteri predefiniti per accedere alla risorsa. I criteri di autorizzazione predefiniti vengono configurati per l'uso dello schema di autenticazione predefinito, configurato dallo AddIdentityServerJwt
schema di criteri indicato in precedenza, rendendo configurato JwtBearerHandler
da tale metodo helper il gestore predefinito per le richieste all'app.
Nel file si noti che lo stesso DbContext
viene usato in Identity con l'eccezione che estende ApiAuthorizationDbContext
(una classe più derivata da IdentityDbContext
) per includere lo schema per IdentityServer.
Per ottenere il controllo completo dello schema del database, ereditare da una delle classi disponibili IdentityDbContext
e configurare il contesto per includere lo Identity schema chiamando builder.ConfigurePersistedGrantContext(_operationalStoreOptions.Value)
sul OnModelCreating
metodo .
Nel file notare l'endpoint di cui è stato effettuato il provisioning per gestire i parametri OIDC che il client deve usare.
appsettings.json
Nel file della radice del progetto è presente una nuova IdentityServer
sezione che descrive l'elenco dei client configurati. Nell'esempio seguente è presente un singolo client. Il nome del client corrisponde al nome dell'app ed è mappato per convenzione al parametro OAuth ClientId
. Il profilo indica il tipo di app configurato. Viene usata internamente per guidare convenzioni che semplificano il processo di configurazione per il server. Sono disponibili diversi profili, come illustrato nella sezione Profili applicazione.
"IdentityServer": {
"Clients": {
"angularindividualpreview3final": {
"Profile": "IdentityServerSPA"
}
}
}
appsettings.Development.json
Nel file della radice del progetto è presente una IdentityServer
sezione che descrive la chiave usata per firmare i token. Quando si esegue la distribuzione nell'ambiente di produzione, è necessario eseguire il provisioning e la distribuzione di una chiave insieme all'app, come illustrato nella sezione Distribuisci in produzione .
"IdentityServer": {
"Key": {
"Type": "Development"
}
}
Il supporto dell'autenticazione e dell'autorizzazione API nel modello Angular si trova nel proprio modulo Angular nella directory ClientApp/src/api-authorization . Il modulo è costituito dagli elementi seguenti:
login.component.ts
: gestisce il flusso di accesso dell'app.logout.component.ts
: gestisce il flusso di disconnessione dell'app.login-menu.component.ts
: widget che visualizza uno dei set di collegamenti seguenti: AuthorizeGuard
della route che può essere aggiunta alle route e richiede l'autenticazione di un utente prima di visitare la route.AuthorizeInterceptor
HTTP che collega il token di accesso alle richieste HTTP in uscita destinate all'API quando l'utente viene autenticato.AuthorizeService
che gestisce i dettagli di livello inferiore del processo di autenticazione ed espone informazioni sull'utente autenticato all'oggetto rest dell'app per l'utilizzo.Il supporto per l'autenticazione e l'autorizzazione API nel modello React risiede nella directory ClientApp/src/components/api-authorization . È costituito dagli elementi seguenti:
Login.js
: gestisce il flusso di accesso dell'app.Logout.js
: gestisce il flusso di disconnessione dell'app.LoginMenu.js
: widget che visualizza uno dei set di collegamenti seguenti: AuthorizeRoute.js
: componente di route che richiede l'autenticazione di un utente prima di eseguire il rendering del Component
componente indicato nel parametro .authService
della classe AuthorizeService
che gestisce i dettagli di livello inferiore del processo di autenticazione ed espone informazioni sull'utente autenticato all'oggetto rest dell'app per l'utilizzo.Dopo aver visto i componenti principali della soluzione, è possibile esaminare in modo più approfondito i singoli scenari per l'app.
Per impostazione predefinita, il sistema è configurato per richiedere facilmente l'autorizzazione per le nuove API. A tale scopo, creare un nuovo controller e aggiungere l'attributo [Authorize]
alla classe controller o a qualsiasi azione all'interno del controller.
Per personalizzare la configurazione del gestore JWT dell'API, configurarne l'istanza JwtBearerOptions :
builder.Services.AddAuthentication()
.AddIdentityServerJwt();
builder.Services.Configure<JwtBearerOptions>(
IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
...
});
Il gestore JWT dell'API genera eventi che consentono il controllo sul processo di autenticazione tramite JwtBearerEvents
. Per fornire supporto per l'autorizzazione API, AddIdentityServerJwt
registra i propri gestori eventi.
Per personalizzare la gestione di un evento, eseguire il wrapping del gestore eventi esistente con logica aggiuntiva in base alle esigenze. Ad esempio:
builder.Services.Configure<JwtBearerOptions>(
IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
var onTokenValidated = options.Events.OnTokenValidated;
options.Events.OnTokenValidated = async context =>
{
await onTokenValidated(context);
...
}
});
Nel codice precedente il OnTokenValidated
gestore eventi viene sostituito con un'implementazione personalizzata. Questa implementazione:
La protezione di una route lato client viene eseguita aggiungendo la protezione dell'autorizzazione all'elenco di misure di sicurezza da eseguire durante la configurazione di una route. Ad esempio, è possibile vedere come viene configurata la fetch-data
route all'interno del modulo Angular dell'app principale:
RouterModule.forRoot([
// ...
{ path: 'fetch-data', component: FetchDataComponent, canActivate: [AuthorizeGuard] },
])
È importante ricordare che la protezione di una route non protegge l'endpoint effettivo (che richiede ancora un [Authorize]
attributo applicato), ma che impedisce solo all'utente di passare alla route sul lato client specificata quando non viene autenticata.
L'autenticazione delle richieste alle API ospitate insieme all'app viene eseguita automaticamente tramite l'uso dell'intercettore client HTTP definito dall'app.
Proteggere una route lato client usando il AuthorizeRoute
componente anziché il componente normale Route
. Si noti ad esempio come la fetch-data
route viene configurata all'interno del App
componente:
<AuthorizeRoute path='/fetch-data' component={FetchData} />
Protezione di una route:
[Authorize]
attributo applicato).L'autenticazione delle richieste con React viene eseguita prima importando l'istanza authService
da AuthorizeService
. Il token di accesso viene recuperato da authService
e viene collegato alla richiesta, come illustrato di seguito. Nei componenti React questo lavoro viene in genere eseguito nel metodo del componentDidMount
ciclo di vita o come risultato di un'interazione dell'utente.
import authService from './api-authorization/AuthorizeService'
async populateWeatherData() {
const token = await authService.getAccessToken();
const response = await fetch('api/SampleData/WeatherForecasts', {
headers: !token ? {} : { 'Authorization': `Bearer ${token}` }
});
const data = await response.json();
this.setState({ forecasts: data, loading: false });
}
Per distribuire l'app nell'ambiente di produzione, è necessario effettuare il provisioning delle risorse seguenti:
Nel pannello di hosting Web creare o caricare il certificato. Quindi, nel file dell'app appsettings.json
, modificare la IdentityServer
sezione in modo da includere i dettagli della chiave. Ad esempio:
"IdentityServer": {
"Key": {
"Type": "Store",
"StoreName": "WebHosting",
"StoreLocation": "CurrentUser",
"Name": "CN=MyApplication"
}
}
Nell'esempio precedente:
StoreName
rappresenta il nome dell'archivio certificati in cui è archiviato il certificato. In questo caso, punta all'archivio di hosting Web.StoreLocation
rappresenta dove caricare il certificato da (CurrentUser
in questo caso).Name
corrisponde all'oggetto distinto per il certificato.Questa sezione descrive la distribuzione dell'app in app Azure Servizio usando un certificato archiviato nell'archivio certificati. Per modificare l'app per caricare un certificato dall'archivio certificati, è necessario un piano di servizio di livello Standard o superiore quando si configura l'app nel portale di Azure in un passaggio successivo.
Nel file dell'app appsettings.json
modificare la IdentityServer
sezione in modo da includere i dettagli chiave:
"IdentityServer": {
"Key": {
"Type": "Store",
"StoreName": "My",
"StoreLocation": "CurrentUser",
"Name": "CN=MyApplication"
}
}
CurrentUser
o LocalMachine
).Per eseguire la distribuzione nel servizio app Azure, seguire la procedura descritta in Distribuire l'app in Azure, che illustra come creare le risorse di Azure necessarie e distribuire l'app nell'ambiente di produzione.
Dopo aver seguito le istruzioni precedenti, l'app viene distribuita in Azure ma non è ancora funzionante. Il certificato usato dall'app deve essere configurato nel portale di Azure. Individuare l'identificazione personale per il certificato e seguire i passaggi descritti in Caricare i certificati.
Anche se questi passaggi indicano SSL, è disponibile una sezione Certificati privati nella portale di Azure in cui è possibile caricare il certificato di cui è stato effettuato il provisioning da usare con l'app.
Dopo aver configurato l'app e le impostazioni dell'app nel portale di Azure, riavviare l'app nel portale.
Il supporto per l'autorizzazione API si basa su IdentityServer con un set di convenzioni, valori predefiniti e miglioramenti per semplificare l'esperienza per le applicazioni a pagina singola. Inutile dire che la piena potenza di IdentityServer è disponibile in background se le integrazioni di ASP.NET Core non coprono lo scenario. Il supporto di ASP.NET Core è incentrato sulle app "proprietarie", in cui tutte le app vengono create e distribuite dall'organizzazione. Di conseguenza, il supporto non viene offerto per elementi come il consenso o la federazione. Per questi scenari, usare IdentityServer e seguire la relativa documentazione.
I profili applicazione sono configurazioni predefinite per le app che definiscono ulteriormente i relativi parametri. Al momento sono supportati i profili seguenti:
IdentityServerSPA
: rappresenta un'applicazione a pagina singola ospitata insieme a IdentityServer come singola unità.
redirect_uri
valore predefinito è /authentication/login-callback
.post_logout_redirect_uri
valore predefinito è /authentication/logout-callback
.openid
profile
e ogni ambito definito per le API nell'app.id_token token
o ognuno di essi singolarmente (id_token
, token
).fragment
.SPA
: rappresenta un'applicazione a pagina singola non ospitata con IdentityServer.
openid
profile
e ogni ambito definito per le API nell'app.id_token token
o ognuno di essi singolarmente (id_token
, token
).fragment
.IdentityServerJwt
: rappresenta un'API ospitata insieme a IdentityServer.
API
: rappresenta un'API non ospitata con IdentityServer.
Configurare le app tramite il sistema di configurazione aggiungendole all'elenco di Clients
o Resources
.
Configurare la proprietà e post_logout_redirect_uri
di redirect_uri
ogni client, come illustrato nell'esempio seguente:
"IdentityServer": {
"Clients": {
"MySPA": {
"Profile": "SPA",
"RedirectUri": "https://www.example.com/authentication/login-callback",
"LogoutUri": "https://www.example.com/authentication/logout-callback"
}
}
}
Quando si configurano le risorse, è possibile configurare gli ambiti per la risorsa come illustrato di seguito:
"IdentityServer": {
"Resources": {
"MyExternalApi": {
"Profile": "API",
"Scopes": "a b c"
}
}
}
È anche possibile configurare i client e le risorse tramite il codice usando un overload di AddApiAuthorization
che esegue un'azione per configurare le opzioni.
AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options =>
{
options.Clients.AddSPA(
"My SPA", spa =>
spa.WithRedirectUri("http://www.example.com/authentication/login-callback")
.WithLogoutRedirectUri(
"http://www.example.com/authentication/logout-callback"));
options.ApiResources.AddApiResource("MyExternalApi", resource =>
resource.WithScopes("a", "b", "c"));
});
I modelli di ASP.NET Core 3.1 e versioni successive offrono l'autenticazione in App a pagina singola usando il supporto per l'autorizzazione api. ASP.NET Core Identity per l'autenticazione e l'archiviazione degli utenti viene combinato con IdentityServer per l'implementazione di OpenID Connect.
È stato aggiunto un parametro di autenticazione ai modelli di progetto Angular e React simili al parametro di autenticazione nei modelli di progetto Applicazione Web (Model-View-Controller) e Applicazione Web (Razor Pages). I valori dei parametri consentiti sono None e Individual. Il modello di progetto React ejs Redux non supporta attualmente il parametro di autenticazione.
L'autenticazione e l'autorizzazione dell'utente possono essere usate sia con Angular che con i criteri di servizio React. Aprire una shell dei comandi ed eseguire il comando seguente:
Angular:
dotnet new angular -o <output_directory_name>
React:
dotnet new react -o <output_directory_name> -au Individual
Il comando precedente crea un'app ASP.NET Core con una directory ClientApp contenente l'applicazione a pagina singola.
Le sezioni seguenti descrivono le aggiunte al progetto quando è incluso il supporto per l'autenticazione:
Gli esempi di codice seguenti si basano sul pacchetto NuGet Microsoft.AspNetCore.ApiAuthorization.IdentityServer . Gli esempi configurano l'autenticazione e l'autorizzazione api usando i AddApiAuthorization metodi di estensione e AddIdentityServerJwt . I progetti che usano i modelli di progetto React o Angular SPA con l'autenticazione includono un riferimento a questo pacchetto.
La Startup
classe presenta le aggiunte seguenti:
All'interno del Startup.ConfigureServices
metodo :
Identity con l'interfaccia utente predefinita:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<ApplicationUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
IdentityServer con un metodo helper aggiuntivo AddApiAuthorization
che configura alcune convenzioni predefinite ASP.NET Core su IdentityServer:
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
Autenticazione con un metodo helper aggiuntivo AddIdentityServerJwt
che configura l'app per convalidare i token JWT prodotti da IdentityServer:
services.AddAuthentication()
.AddIdentityServerJwt();
All'interno del Startup.Configure
metodo :
Middleware di autenticazione responsabile della convalida delle credenziali della richiesta e dell'impostazione dell'utente nel contesto della richiesta:
app.UseAuthentication();
Middleware IdentityServer che espone gli endpoint OpenID Connect:
app.UseIdentityServer();
Avviso
Questo articolo illustra l'uso di stringa di connessione. Con un database locale l'utente non deve essere autenticato, ma nell'ambiente di produzione stringa di connessione talvolta include una password per l'autenticazione. Una credenziale della password del proprietario della risorsa (ROPC) è un rischio per la sicurezza che deve essere evitato nei database di produzione. Le app di produzione devono usare il flusso di autenticazione più sicuro disponibile. Per altre informazioni sull'autenticazione per le app distribuite in ambienti di test o di produzione, vedere Proteggere i flussi di autenticazione.
Per le distribuzioni del servizio app Azure in Linux, specificare l'autorità di certificazione in modo esplicito in Startup.ConfigureServices
:
services.Configure<JwtBearerOptions>(
IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
options.Authority = "{AUTHORITY}";
});
Nel codice precedente, il {AUTHORITY}
segnaposto è l'oggetto Authority da usare quando si effettuano chiamate OpenID Connect.
Esempio:
options.Authority = "https://contoso-service.azurewebsites.net";
Questo metodo helper configura IdentityServer per l'uso della configurazione supportata. IdentityServer è un framework potente ed estendibile per la gestione dei problemi di sicurezza delle app. Allo stesso tempo, che espone complessità non necessarie per gli scenari più comuni. Di conseguenza, viene fornito un set di convenzioni e opzioni di configurazione che sono considerate un buon punto di partenza. Una volta modificata l'autenticazione, la potenza completa di IdentityServer è ancora disponibile per personalizzare l'autenticazione in base alle proprie esigenze.
Questo metodo helper configura uno schema di criteri per l'app come gestore di autenticazione predefinito. Il criterio è configurato per consentire la Identity gestione di tutte le richieste indirizzate a qualsiasi sottopercorso nello Identity spazio URL "/Identity". JwtBearerHandler
Gestisce tutte le altre richieste. Inoltre, questo metodo registra una <<ApplicationName>>API
risorsa API con IdentityServer con un ambito predefinito e <<ApplicationName>>API
configura il middleware del token di connessione JWT per convalidare i token rilasciati da IdentityServer per l'app.
Nel file osservare l'attributo [Authorize]
applicato alla classe che indica che l'utente deve essere autorizzato in base ai criteri predefiniti per accedere alla risorsa. I criteri di autorizzazione predefiniti vengono configurati per l'uso dello schema di autenticazione predefinito, configurato dallo AddIdentityServerJwt
schema di criteri indicato in precedenza, rendendo configurato JwtBearerHandler
da tale metodo helper il gestore predefinito per le richieste all'app.
Nel file si noti che lo stesso DbContext
viene usato in Identity con l'eccezione che estende ApiAuthorizationDbContext
(una classe più derivata da IdentityDbContext
) per includere lo schema per IdentityServer.
Per ottenere il controllo completo dello schema del database, ereditare da una delle classi disponibili IdentityDbContext
e configurare il contesto per includere lo Identity schema chiamando builder.ConfigurePersistedGrantContext(_operationalStoreOptions.Value)
sul OnModelCreating
metodo .
Nel file notare l'endpoint di cui è stato effettuato il provisioning per gestire i parametri OIDC che il client deve usare.
appsettings.json
Nel file della radice del progetto è presente una nuova IdentityServer
sezione che descrive l'elenco dei client configurati. Nell'esempio seguente è presente un singolo client. Il nome del client corrisponde al nome dell'app ed è mappato per convenzione al parametro OAuth ClientId
. Il profilo indica il tipo di app configurato. Viene usata internamente per guidare convenzioni che semplificano il processo di configurazione per il server. Sono disponibili diversi profili, come illustrato nella sezione Profili applicazione.
"IdentityServer": {
"Clients": {
"angularindividualpreview3final": {
"Profile": "IdentityServerSPA"
}
}
}
appsettings.Development.json
Nel file della radice del progetto è presente una IdentityServer
sezione che descrive la chiave usata per firmare i token. Quando si esegue la distribuzione nell'ambiente di produzione, è necessario eseguire il provisioning e la distribuzione di una chiave insieme all'app, come illustrato nella sezione Distribuisci in produzione .
"IdentityServer": {
"Key": {
"Type": "Development"
}
}
Il supporto dell'autenticazione e dell'autorizzazione API nel modello Angular si trova nel proprio modulo Angular nella directory ClientApp/src/api-authorization . Il modulo è costituito dagli elementi seguenti:
login.component.ts
: gestisce il flusso di accesso dell'app.logout.component.ts
: gestisce il flusso di disconnessione dell'app.login-menu.component.ts
: widget che visualizza uno dei set di collegamenti seguenti: AuthorizeGuard
della route che può essere aggiunta alle route e richiede l'autenticazione di un utente prima di visitare la route.AuthorizeInterceptor
HTTP che collega il token di accesso alle richieste HTTP in uscita destinate all'API quando l'utente viene autenticato.AuthorizeService
che gestisce i dettagli di livello inferiore del processo di autenticazione ed espone informazioni sull'utente autenticato all'oggetto rest dell'app per l'utilizzo.Il supporto per l'autenticazione e l'autorizzazione API nel modello React risiede nella directory ClientApp/src/components/api-authorization . È costituito dagli elementi seguenti:
Login.js
: gestisce il flusso di accesso dell'app.Logout.js
: gestisce il flusso di disconnessione dell'app.LoginMenu.js
: widget che visualizza uno dei set di collegamenti seguenti: AuthorizeRoute.js
: componente di route che richiede l'autenticazione di un utente prima di eseguire il rendering del Component
componente indicato nel parametro .authService
della classe AuthorizeService
che gestisce i dettagli di livello inferiore del processo di autenticazione ed espone informazioni sull'utente autenticato all'oggetto rest dell'app per l'utilizzo.Dopo aver visto i componenti principali della soluzione, è possibile esaminare in modo più approfondito i singoli scenari per l'app.
Per impostazione predefinita, il sistema è configurato per richiedere facilmente l'autorizzazione per le nuove API. A tale scopo, creare un nuovo controller e aggiungere l'attributo [Authorize]
alla classe controller o a qualsiasi azione all'interno del controller.
Per personalizzare la configurazione del gestore JWT dell'API, configurarne l'istanza JwtBearerOptions :
services.AddAuthentication()
.AddIdentityServerJwt();
services.Configure<JwtBearerOptions>(
IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
...
});
Il gestore JWT dell'API genera eventi che consentono il controllo sul processo di autenticazione tramite JwtBearerEvents
. Per fornire supporto per l'autorizzazione API, AddIdentityServerJwt
registra i propri gestori eventi.
Per personalizzare la gestione di un evento, eseguire il wrapping del gestore eventi esistente con logica aggiuntiva in base alle esigenze. Ad esempio:
services.Configure<JwtBearerOptions>(
IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
var onTokenValidated = options.Events.OnTokenValidated;
options.Events.OnTokenValidated = async context =>
{
await onTokenValidated(context);
...
}
});
Nel codice precedente il OnTokenValidated
gestore eventi viene sostituito con un'implementazione personalizzata. Questa implementazione:
La protezione di una route lato client viene eseguita aggiungendo la protezione dell'autorizzazione all'elenco di misure di sicurezza da eseguire durante la configurazione di una route. Ad esempio, è possibile vedere come viene configurata la fetch-data
route all'interno del modulo Angular dell'app principale:
RouterModule.forRoot([
// ...
{ path: 'fetch-data', component: FetchDataComponent, canActivate: [AuthorizeGuard] },
])
È importante ricordare che la protezione di una route non protegge l'endpoint effettivo (che richiede ancora un [Authorize]
attributo applicato), ma che impedisce solo all'utente di passare alla route sul lato client specificata quando non viene autenticata.
L'autenticazione delle richieste alle API ospitate insieme all'app viene eseguita automaticamente tramite l'uso dell'intercettore client HTTP definito dall'app.
Proteggere una route lato client usando il AuthorizeRoute
componente anziché il componente normale Route
. Si noti ad esempio come la fetch-data
route viene configurata all'interno del App
componente:
<AuthorizeRoute path='/fetch-data' component={FetchData} />
Protezione di una route:
[Authorize]
attributo applicato).L'autenticazione delle richieste con React viene eseguita prima importando l'istanza authService
da AuthorizeService
. Il token di accesso viene recuperato da authService
e viene collegato alla richiesta, come illustrato di seguito. Nei componenti React questo lavoro viene in genere eseguito nel metodo del componentDidMount
ciclo di vita o come risultato di un'interazione dell'utente.
import authService from './api-authorization/AuthorizeService'
async populateWeatherData() {
const token = await authService.getAccessToken();
const response = await fetch('api/SampleData/WeatherForecasts', {
headers: !token ? {} : { 'Authorization': `Bearer ${token}` }
});
const data = await response.json();
this.setState({ forecasts: data, loading: false });
}
Per distribuire l'app nell'ambiente di produzione, è necessario effettuare il provisioning delle risorse seguenti:
Nel pannello di hosting Web creare o caricare il certificato. Quindi, nel file dell'app appsettings.json
, modificare la IdentityServer
sezione in modo da includere i dettagli della chiave. Ad esempio:
"IdentityServer": {
"Key": {
"Type": "Store",
"StoreName": "WebHosting",
"StoreLocation": "CurrentUser",
"Name": "CN=MyApplication"
}
}
Nell'esempio precedente:
StoreName
rappresenta il nome dell'archivio certificati in cui è archiviato il certificato. In questo caso, punta all'archivio di hosting Web.StoreLocation
rappresenta dove caricare il certificato da (CurrentUser
in questo caso).Name
corrisponde all'oggetto distinto per il certificato.Questa sezione descrive la distribuzione dell'app in app Azure Servizio usando un certificato archiviato nell'archivio certificati. Per modificare l'app per caricare un certificato dall'archivio certificati, è necessario un piano di servizio di livello Standard o superiore quando si configura l'app nel portale di Azure in un passaggio successivo.
Nel file dell'app appsettings.json
modificare la IdentityServer
sezione in modo da includere i dettagli chiave:
"IdentityServer": {
"Key": {
"Type": "Store",
"StoreName": "My",
"StoreLocation": "CurrentUser",
"Name": "CN=MyApplication"
}
}
CurrentUser
o LocalMachine
).Per eseguire la distribuzione nel servizio app Azure, seguire la procedura descritta in Distribuire l'app in Azure, che illustra come creare le risorse di Azure necessarie e distribuire l'app nell'ambiente di produzione.
Dopo aver seguito le istruzioni precedenti, l'app viene distribuita in Azure ma non è ancora funzionante. Il certificato usato dall'app deve essere configurato nel portale di Azure. Individuare l'identificazione personale per il certificato e seguire i passaggi descritti in Caricare i certificati.
Anche se questi passaggi indicano SSL, è disponibile una sezione Certificati privati nella portale di Azure in cui è possibile caricare il certificato di cui è stato effettuato il provisioning da usare con l'app.
Dopo aver configurato l'app e le impostazioni dell'app nel portale di Azure, riavviare l'app nel portale.
Il supporto per l'autorizzazione API si basa su IdentityServer con un set di convenzioni, valori predefiniti e miglioramenti per semplificare l'esperienza per le applicazioni a pagina singola. Inutile dire che la piena potenza di IdentityServer è disponibile in background se le integrazioni di ASP.NET Core non coprono lo scenario. Il supporto di ASP.NET Core è incentrato sulle app "proprietarie", in cui tutte le app vengono create e distribuite dall'organizzazione. Di conseguenza, il supporto non viene offerto per elementi come il consenso o la federazione. Per questi scenari, usare IdentityServer e seguire la relativa documentazione.
I profili applicazione sono configurazioni predefinite per le app che definiscono ulteriormente i relativi parametri. Al momento sono supportati i profili seguenti:
IdentityServerSPA
: rappresenta un'applicazione a pagina singola ospitata insieme a IdentityServer come singola unità.
redirect_uri
valore predefinito è /authentication/login-callback
.post_logout_redirect_uri
valore predefinito è /authentication/logout-callback
.openid
profile
e ogni ambito definito per le API nell'app.id_token token
o ognuno di essi singolarmente (id_token
, token
).fragment
.SPA
: rappresenta un'applicazione a pagina singola non ospitata con IdentityServer.
openid
profile
e ogni ambito definito per le API nell'app.id_token token
o ognuno di essi singolarmente (id_token
, token
).fragment
.IdentityServerJwt
: rappresenta un'API ospitata insieme a IdentityServer.
API
: rappresenta un'API non ospitata con IdentityServer.
Configurare le app tramite il sistema di configurazione aggiungendole all'elenco di Clients
o Resources
.
Configurare la proprietà e post_logout_redirect_uri
di redirect_uri
ogni client, come illustrato nell'esempio seguente:
"IdentityServer": {
"Clients": {
"MySPA": {
"Profile": "SPA",
"RedirectUri": "https://www.example.com/authentication/login-callback",
"LogoutUri": "https://www.example.com/authentication/logout-callback"
}
}
}
Quando si configurano le risorse, è possibile configurare gli ambiti per la risorsa come illustrato di seguito:
"IdentityServer": {
"Resources": {
"MyExternalApi": {
"Profile": "API",
"Scopes": "a b c"
}
}
}
È anche possibile configurare i client e le risorse tramite il codice usando un overload di AddApiAuthorization
che esegue un'azione per configurare le opzioni.
AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options =>
{
options.Clients.AddSPA(
"My SPA", spa =>
spa.WithRedirectUri("http://www.example.com/authentication/login-callback")
.WithLogoutRedirectUri(
"http://www.example.com/authentication/logout-callback"));
options.ApiResources.AddApiResource("MyExternalApi", resource =>
resource.WithScopes("a", "b", "c"));
});
Feedback su ASP.NET Core
ASP.NET Core è un progetto di open source. Selezionare un collegamento per fornire feedback:
Eventi
19 nov, 23 - 21 nov, 23
Partecipa alle sessioni online di Microsoft Ignite create per espandere le tue competenze e aiutarti a risolvere i problemi complessi di oggi.
Iscriviti subito