Verwenden von Identity zum Schützen eines Web-API-Back-Ends für SPAs
Hinweis
Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.
Warnung
Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der .NET- und .NET Core-Supportrichtlinie. Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.
Wichtig
Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.
Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.
ASP.NET Core Identity stellt APIs für die Authentifizierung, Autorisierung und Verwaltung der identity bereit. Die APIs ermöglichen es, Endpunkte eines Web-API-Back-Ends mit cookie-basierter Authentifizierung zu schützen. Eine tokenbasierte Option ist für Clients verfügbar, die keine Cookies verwenden können, doch wenn Sie diese verwenden, sind Sie dafür verantwortlich, sicherzustellen, dass die Token sicher bleiben. Es wird empfohlen, s für browserbasierte Anwendungen zu verwenden, da der Browser sie standardmäßig automatisch verarbeitet, ohne sie JavaScript verfügbar zu machen.
In diesem Artikel erfahren Sie, wie Sie Identity verwenden, um ein Web-API-Back-End für SPAs wie Angular-, React- und Vue-Apps zu schützen. Die gleichen Back-End-APIs können zum Schützen von Blazor WebAssembly-Apps verwendet werden.
Voraussetzungen
Die in diesem Artikel gezeigten Schritte fügen einer ASP.NET Core-Web-API-App Authentifizierungs- und Autorisierungsfunktionen hinzu, für die Folgendes gilt:
- noch nicht für die Authentifizierung konfiguriert ist
- Sie ist auf
net8.0
oder höhere Versionen ausgerichtet. - Sie kann eine minimale API oder eine controllerbasierte API sein.
Einige der Testanweisungen in diesem Artikel verwenden die Swagger-Benutzeroberfläche, die in der Projektvorlage enthalten ist. Die Swagger-Benutzeroberfläche ist nicht erforderlich, um Identity mit einem Web-API-Back-End zu verwenden.
Installieren von NuGet-Paketen
Installieren Sie die folgenden NuGet-Pakete:
Microsoft.AspNetCore.Identity.EntityFrameworkCore
: Ermöglicht es Identity, mit Entity Framework Core (EF Core) zu arbeiten.- Ein Paket, das es EF Core ermöglicht, mit einer Datenbank zu arbeiten – beispielsweise eines der folgenden Pakete:
Verwenden Sie für den schnellstmöglichen Einstieg die In-Memory-Datenbank.
Ändern Sie die Datenbank später in SQLite oder SQL Server, um Benutzerdaten beim Testen oder für die Produktionsverwendung sitzungsübergreifend zu speichern. Dies führt zu einem gewissen Maß an Komplexität im Vergleich zum In-Memory-Modell, da die Datenbank über Migrationen erstellt werden muss, wie im Tutorial Erste Schritte mit EF Core gezeigt.
Installieren Sie diese Pakete über den NuGet-Paket-Manager in Visual Studio oder mithilfe des CLI-Befehls dotnet add package.
Erstellen Sie einen IdentityDbContext
.
Fügen Sie eine Klasse namens ApplicationDbContext
hinzu, die von IdentityDbContext<TUser> erbt:
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
public class ApplicationDbContext : IdentityDbContext<IdentityUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) :
base(options)
{ }
}
Der gezeigte Code enthält einen speziellen Konstruktor, mit dem die Datenbank für verschiedene Umgebungen konfiguriert werden kann.
Fügen Sie bei Bedarf eine oder mehrere der folgenden using
-Direktiven hinzu, wenn Sie den in diesen Schritten gezeigten Code hinzufügen.
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
Konfigurieren des EF Core-Kontexts
Wie bereits erwähnt, ist es am einfachsten, zunächst die In-Memory-Datenbank zu verwenden. Beim In-Memory-Modell beginnt jede Ausführung mit einer neuen Datenbank, und es müssen keine Migrationen verwendet werden. Fügen Sie nach dem Aufruf von WebApplication.CreateBuilder(args)
den folgenden Code hinzu, um Identity für die Verwendung einer In-Memory-Datenbank zu konfigurieren:
builder.Services.AddDbContext<ApplicationDbContext>(
options => options.UseInMemoryDatabase("AppDb"));
Ändern Sie die Datenbank später in SQLite oder SQL Server, um Benutzerdaten beim Testen oder für die Verwendung in der Produktion sitzungsübergreifend zu speichern.
Hinzufügen von Identity-Diensten zum Container
Nach dem Aufruf von WebApplication.CreateBuilder(args)
muss AddAuthorization aufgerufen werden, um dem DI-Container (Dependency Injection) Dienste hinzuzufügen:
builder.Services.AddAuthorization();
Aktivieren von Identity-APIs
Nach dem Aufruf von WebApplication.CreateBuilder(args)
müssen AddIdentityApiEndpoints<TUser>(IServiceCollection) und AddEntityFrameworkStores<TContext>(IdentityBuilder) aufgerufen werden.
builder.Services.AddIdentityApiEndpoints<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
Standardmäßig werden sowohl Cookies als auch proprietäre Token aktiviert. Cookies und Token werden bei der Anmeldung ausgegeben, wenn der Abfragezeichenfolgenparameter useCookies
am Anmeldeendpunkt true
lautet.
Zuordnen von Identity-Routen
Nach dem Aufruf von builder.Build()
muss MapIdentityApi<TUser>(IEndpointRouteBuilder) aufgerufen werden, um die Identity-Endpunkte zuzuordnen:
app.MapIdentityApi<IdentityUser>();
Sichere ausgewählte Endpunkte
Verwenden Sie zum Schützen eines Endpunkts die RequireAuthorization-Erweiterungsmethode für den Map{Method}
-Aufruf, der die Route definiert. Beispiel:
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();
Die RequireAuthorization
-Methode kann auch für Folgendes verwendet werden:
Schützen von Swagger-Benutzeroberflächenendpunkten, wie im folgenden Beispiel gezeigt:
app.MapSwagger().RequireAuthorization();
Schützen mit einem bestimmten Anspruch oder einer bestimmten Berechtigung, wie im folgenden Beispiel gezeigt:
.RequireAuthorization("Admin");
Schützen Sie die Endpunkte in einem controllerbasierten Web-API-Projekt, indem Sie das Attribut [Authorize
] auf einen Controller oder eine Aktion anwenden.
Testen der API
Eine schnelle Möglichkeit zum Testen der Authentifizierung besteht darin, die In-Memory-Datenbank und die Swagger-Benutzeroberfläche zu verwenden, die in der Projektvorlage enthalten ist. Die folgenden Schritte zeigen, wie Sie die API mit der Swagger-Benutzeroberfläche testen. Vergewissern Sie sich, dass die Endpunkte der Swagger-Benutzeroberfläche nicht geschützt sind.
Versuchen, auf einen geschützten Endpunkt zuzugreifen
- Führen Sie die App aus, und navigieren Sie zur Swagger-Benutzeroberfläche.
- Erweitern Sie einen geschützten Endpunkt (z. B.
/weatherforecast
) in einem Projekt, das von der Web-API-Vorlage erstellt wurde. - Wählen Sie Ausprobieren aus.
- Wählen Sie Execute(Ausführen). Die Antwort lautet:
401 - not authorized
.
Testen der Registrierung
Erweitern Sie
/register
, und wählen Sie Ausprobieren aus.Im Abschnitt Parameter der Benutzeroberfläche wird ein exemplarischer Anforderungstext angezeigt:
{ "email": "string", "password": "string" }
Ersetzen Sie „string“ durch eine gültige E-Mail-Adresse und ein gültiges Kennwort, und wählen Sie dann Ausführen aus.
Um den Standardregeln für Kennwörter zu entsprechen, muss das Kennwort mindestens sechs Zeichen lang sein und mindestens eins der folgenden Zeichen enthalten:
- Großbuchstabe
- Kleinbuchstabe
- Numerische Ziffer
- Nicht alphanumerisches Zeichen
Wenn Sie eine ungültige E-Mail-Adresse oder ein ungültiges Kennwort eingeben, enthält das Ergebnis die Überprüfungsfehler. Hier sehen Sie ein Beispiel für einen Antworttext mit Überprüfungsfehlern:
{ "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')." ] } }
Die Fehler werden im Format ProblemDetails zurückgegeben, sodass der Client sie analysieren und bei Bedarf Validierungsfehler anzeigen kann.
Eine erfolgreiche Registrierung führt zu einer Antwort vom Typ
200 - OK
.
Testen der Anmeldung
Erweitern Sie
/login
, und wählen Sie Ausprobieren aus. Der exemplarische Anforderungstext enthält zwei zusätzliche Parameter:{ "email": "string", "password": "string", "twoFactorCode": "string", "twoFactorRecoveryCode": "string" }
Die zusätzlichen JSON-Eigenschaften werden für dieses Beispiel nicht benötigt und können gelöscht werden. Setzen Sie
useCookies
auftrue
.Ersetzen Sie „string“ durch die E-Mail-Adresse und das Kennwort, die Sie bei der Registrierung verwendet haben, und wählen Sie anschließend Ausführen aus.
Eine erfolgreiche Anmeldung führt zu einer Antwort vom Typ
200 - OK
mit einem cookie im Antwortheader.
Erneutes Testen des geschützten Endpunkts
Führen Sie nach einer erfolgreichen Anmeldung erneut den geschützten Endpunkt aus. Das cookie für die Authentifizierung wird automatisch zusammen mit der Anforderung gesendet, und der Endpunkt wird autorisiert. Die Cookie-basierte Authentifizierung ist sicher in den Browser integriert und funktioniert reibungslos.
Testen mit browserfremden Clients
Einige Webclients enthalten möglicherweise standardmäßig keine Cookies im Header:
Wenn Sie ein Tool zum Testen von APIs verwenden, müssen Cookies möglicherweise in den Einstellungen aktiviert werden.
Die JavaScript
fetch
-API enthält standardmäßig keine Cookies. Aktivieren Sie sie, indem Siecredentials
in den Optionen auf den Wertinclude
festlegen.Bei einer in einer Blazor WebAssembly-App ausgeführten
HttpClient
-Instanz mussHttpRequestMessage
Anmeldeinformationen enthalten. Beispiel:request.SetBrowserRequestCredential(BrowserRequestCredentials.Include);
Verwenden der tokenbasierten Authentifizierung
Es wird empfohlen, Cookies für browserbasierte Anwendungen zu verwenden da der Browser sie standardmäßig automatisch verarbeitet, ohne sie JavaScript verfügbar zu machen.
Ein benutzerdefiniertes Token (also ein proprietäres Token der ASP.NET Core-identity-Plattform) wird ausgegeben und kann zum Authentifizieren nachfolgender Anforderungen verwendet werden. Das Token wird im Authorization
-Header als Bearertoken übergeben. Außerdem wird ein Aktualisierungstoken bereitgestellt. Mit diesem Token kann die Anwendung ein neues Token anfordern, wenn das alte abläuft, ohne dass sich die Benutzer*innen erneut anmelden müssen.
Die Token sind standardmäßig keine JSON-Webtoken (JWTs). Die Verwendung benutzerdefinierter Token ist beabsichtigt, da die integrierte Identity-API in erster Linie für einfache Szenarien vorgesehen ist. Die Tokenoption ist nicht als vollständiger Identitätsdienstanbieter oder Tokenserver gedacht, sondern als Alternative zur Cookie-Option für Clients, die keine Cookies verwenden können.
Um die tokenbasierte Authentifizierung zu verwenden, legen Sie den useCookies
-Abfragezeichenfolgenparameter beim Aufrufen des /login
-Endpunkts auf false
fest. Token verwenden das Bearerauthentifizierungsschema. Wenn Sie das vom Aufruf von /login
zurückgegebene Token verwenden, sollten nachfolgende Aufrufe von geschützten Endpunkten den Header Authorization: Bearer <token>
hinzufügen, wobei <token>
das Zugriffstoken ist. Weitere Informationen finden Sie unter Verwenden des POST /login
-Endpunkts weiter unten in diesem Artikel.
Abmelden
Um Benutzer*innen eine Möglichkeit zum Abmelden bereitzustellen, definieren Sie einen /logout
-Endpunkt wie im folgenden Beispiel:
app.MapPost("/logout", async (SignInManager<IdentityUser> signInManager,
[FromBody] object empty) =>
{
if (empty != null)
{
await signInManager.SignOutAsync();
return Results.Ok();
}
return Results.Unauthorized();
})
.WithOpenApi()
.RequireAuthorization();
Stellen Sie beim Aufrufen dieses Endpunkts ein leeres JSON-Objekt ({}
) im Anforderungstext bereit. Der folgende Code ist ein Beispiel für einen Aufruf des Abmeldeendpunkts:
public signOut() {
return this.http.post('/logout', {}, {
withCredentials: true,
observe: 'response',
responseType: 'text'
Die MapIdentityApi<TUser>
-Endpunkte
Der Aufruf von MapIdentityApi<TUser>
fügt der App die folgenden Endpunkte hinzu:
POST /register
POST /login
POST /refresh
GET /confirmEmail
POST /resendConfirmationEmail
POST /forgotPassword
POST /resetPassword
POST /manage/2fa
GET /manage/info
POST /manage/info
Verwenden des POST /register
-Endpunkts
Der Anforderungstext muss über Email- und Password-Eigenschaften verfügen:
{
"email": "string",
"password": "string",
}
Weitere Informationen finden Sie unter:
- Testen der Registrierung weiter oben in diesem Artikel
- RegisterRequest.
Verwenden des POST /login
-Endpunkts
Im Anforderungstext sind Email und Password erforderlich. Wenn die Zwei-Faktor-Authentifizierung (2FA) aktiviert ist, ist entweder TwoFactorCode oder TwoFactorRecoveryCode erforderlich. Wenn 2FA nicht aktiviert ist, lassen Sie sowohl twoFactorCode
als auch twoFactorRecoveryCode
weg. Weitere Informationen finden Sie unter Verwenden des POST /manage/2fa
-Endpunkts weiter unten in diesem Artikel.
Hier ist ein Anforderungstextbeispiel mit nicht aktivierter 2FA:
{
"email": "string",
"password": "string"
}
Hier sind Anforderungstextbeispiele mit aktivierter 2FA:
-
{ "email": "string", "password": "string", "twoFactorCode": "string", }
-
{ "email": "string", "password": "string", "twoFactorRecoveryCode": "string" }
Der Endpunkt erwartet einen Abfragezeichenfolgenparameter:
useCookies
: Für die cookie-basierte Authentifizierung auftrue
festgelegt. Legen Sie diesen Wert auffalse
fest, oder lassen Sie ihn für die tokenbasierte Authentifizierung weg.
Weitere Informationen zur cookie-basierten Authentifizierung finden Sie unter Testen der Anmeldung weiter oben in diesem Artikel.
Tokenbasierte Authentifizierung
Wenn useCookies
gleich false
ist oder weggelassen wird, wird die tokenbasierte Authentifizierung aktiviert. Der Antworttext enthält die folgenden Eigenschaften:
{
"tokenType": "string",
"accessToken": "string",
"expiresIn": 0,
"refreshToken": "string"
}
Weitere Informationen zu diesen Eigenschaften finden Sie unter AccessTokenResponse.
Fügen Sie das Zugriffstoken in einen Header ein, um authentifizierte Anforderungen vorzunehmen, wie im folgenden Beispiel gezeigt.
Authorization: Bearer {access token}
Wenn das Zugriffstoken bald abläuft, rufen Sie den /refresh-Endpunkt auf.
Verwenden des POST /refresh
-Endpunkts
Dieser ist nur zur Verwendung mit tokenbasierter Authentifizierung vorgesehen. Er ruft ein neues Zugriffstoken ab, ohne dass Benutzer*innen gezwungen werden, sich erneut anzumelden. Rufen Sie diesen Endpunkt auf, wenn das Zugriffstoken bald abläuft.
Der Anforderungstext enthält nur RefreshToken. Hier ist ein Anforderungstextbeispiel:
{
"refreshToken": "string"
}
Wenn der Aufruf erfolgreich ist, ist der Antworttext eine neue AccessTokenResponse, wie im folgenden Beispiel gezeigt:
{
"tokenType": "string",
"accessToken": "string",
"expiresIn": 0,
"refreshToken": "string"
}
Verwenden des GET /confirmEmail
-Endpunkts
Wenn Identity für die E-Mail-Bestätigung eingerichtet ist, sendet ein erfolgreicher Aufruf des /register
-Endpunkts eine E-Mail, die einen Link zum /confirmEmail
-Endpunkt enthält. Der Link enthält die folgenden Abfragezeichenfolgenparameter:
userId
code
changedEmail
: nur enthalten, wenn der oder die Benutzer*in die E-Mail-Adresse während der Registrierung geändert hat
Identity stellt Standardtext für die Bestätigungs-E-Mail bereit. Standardmäßig lautet der E-Mail-Betreff „Bestätigen Sie Ihre E-Mail-Adresse“, und der E-Mail-Textkörper sieht wie im folgenden Beispiel aus:
Please confirm your account by <a href='https://contoso.com/confirmEmail?userId={user ID}&code={generated code}&changedEmail={new email address}'>clicking here</a>.
Wenn die RequireConfirmedEmail-Eigenschaft auf true
festgelegt ist, können sich Benutzer*innen erst anmelden, wenn die E-Mail-Adresse durch Klicken auf den Link in der E-Mail bestätigt wird. Der /confirmEmail
-Endpunkt:
- bestätigt die E-Mail-Adresse und ermöglicht es dem oder der Benutzer*in, sich anzumelden
- gibt den Text „Vielen Dank für die Bestätigung Ihrer E-Mail-Adresse“ im Antworttext zurück
Um Identity für die E-Mail-Bestätigung einzurichten, fügen Sie Code in Program.cs
hinzu, um RequireConfirmedEmail
auf true
festzulegen, und fügen Sie eine Klasse hinzu, die IEmailSender im DI-Container implementiert. Zum Beispiel:
builder.Services.Configure<IdentityOptions>(options =>
{
options.SignIn.RequireConfirmedEmail = true;
});
builder.Services.AddTransient<IEmailSender, EmailSender>();
Weitere Informationen finden Sie unter Kontobestätigung und Kennwortwiederherstellung in ASP.NET Core.
Identity stellt Standardtext für die anderen E-Mails bereit, die ebenfalls gesendet werden müssen, z. B. für die 2FA- und Kennwortzurücksetzung. Um diese E-Mails anzupassen, stellen Sie eine benutzerdefinierte Implementierung der IEmailSender
Schnittstelle bereit. Im vorherigen Beispiel ist EmailSender
eine Klasse, die IEmailSender
implementiert. Weitere Informationen, einschließlich eines Beispiels für eine Klasse, die IEmailSender
implementiert, finden Sie unter Kontobestätigung und Kennwortwiederherstellung in ASP.NET Core.
Verwenden des POST /resendConfirmationEmail
-Endpunkts
Dieser sendet nur eine E-Mail, wenn die Adresse für eine*n registrierte*n Benutzer*in gültig ist.
Der Anforderungstext enthält nur Email. Hier ist ein Anforderungstextbeispiel:
{
"email": "string"
}
Weitere Informationen finden Sie unter Verwenden des GET /confirmEmail
-Endpunkts weiter oben in diesem Artikel.
Verwenden des POST /forgotPassword
-Endpunkts
Dieser generiert eine E-Mail, die einen Kennwortzurücksetzungscode enthält. Senden Sie diesen Code mit einem neuen Kennwort an /resetPassword
.
Der Anforderungstext enthält nur Email. Ein Beispiel:
{
"email": "string"
}
Informationen zum Aktivieren von Identity zum Senden von E-Mails finden Sie unter Verwenden des GET /confirmEmail
-Endpunkts.
Verwenden des POST /resetPassword
-Endpunkts
Rufen Sie diesen Endpunkt nach dem Abruf eines Zurücksetzungscodes auf, indem Sie den /forgotPassword
-Endpunkt aufrufen.
Der Anforderungstext erfordert Email, ResetCode und NewPassword. Ein Beispiel:
{
"email": "string",
"resetCode": "string",
"newPassword": "string"
}
Verwenden des POST /manage/2fa
-Endpunkts
Dieser konfiguriert die Zwei-Faktor-Authentifizierung (2FA) für den oder die Benutzer*in. Wenn die 2FA aktiviert ist, ist für die erfolgreiche Anmeldung zusätzlich zur E-Mail-Adresse und dem Kennwort ein Code erforderlich, der von einer Authentifikator-App generiert wird.
2FA aktivieren
So aktivieren Sie die 2FA für den oder die aktuelle*n Benutzer*in:
Rufen Sie den
/manage/2fa
-Endpunkt auf, und senden Sie ein leeres ON-Objekt ({}
) im Anforderungstext.Der Antworttext stellt SharedKey zusammen mit einigen anderen Eigenschaften bereit, die zu diesem Zeitpunkt nicht benötigt werden. Der freigegebene Schlüssel wird zum Einrichten der Authentifikator-App verwendet. Beispiel für einen Antworttext:
{ "sharedKey": "string", "recoveryCodesLeft": 0, "recoveryCodes": null, "isTwoFactorEnabled": false, "isMachineRemembered": false }
Verwenden Sie den freigegebenen Schlüssel, um ein zeitbasiertes Einmalkennwort (TOTP) abzurufen. Weitere Informationen finden Sie unter Aktivieren der QR-Code-Generierung für TOTP-Authentifikator-Apps in ASP.NET Core.
Rufen Sie den
/manage/2fa
-Endpunkt auf, und senden Sie das TOTP und"enable": true
im Anforderungstext. Beispiel:{ "enable": true, "twoFactorCode": "string" }
Der Antworttext bestätigt, dass IsTwoFactorEnabled zutrifft und RecoveryCodesbereitstellt. Die Wiederherstellungscodes werden für die Anmeldung verwendet, wenn die Authentifikator-App nicht verfügbar ist. Beispiel für den Antworttext nach erfolgreicher Aktivierung der 2FA:
{ "sharedKey": "string", "recoveryCodesLeft": 10, "recoveryCodes": [ "string", "string", "string", "string", "string", "string", "string", "string", "string", "string" ], "isTwoFactorEnabled": true, "isMachineRemembered": false }
Anmelden mit 2FA
Rufen Sie den /login
-Endpunkt auf, und übermitteln Sie die E-Mail-Adresse, das Kennwort und das TOTP im Anforderungstext. Beispiel:
{
"email": "string",
"password": "string",
"twoFactorCode": "string"
}
Wenn der oder die Benutzer*in keinen Zugriff auf die Authentifikator-App hat, kann die Anmeldung erfolgen, indem der /login
-Endpunkt mit einem der Wiederherstellungscodes aufgerufen wird, die bei der Aktivierung der 2FA bereitgestellt wurden. Der Anforderungstext sieht wie das folgende Beispiel aus:
{
"email": "string",
"password": "string",
"twoFactorRecoveryCode": "string"
}
Zurücksetzen der Wiederherstellungscodes
Rufen Sie diesen Endpunkt auf, um neue Wiederherstellungscodes zu erhalten, wobei ResetRecoveryCodes auf true
festgelegt sein muss. Hier ist ein Anforderungstextbeispiel:
{
"resetRecoveryCodes": true
}
Zurücksetzen des freigegebenen Schlüssels
Um einen neuen zufälligen freigegebenen Schlüssel abzurufen, rufen Sie diesen Endpunkt auf, wobei ResetSharedKey auf true
festgelegt sein muss. Hier ist ein Anforderungstextbeispiel:
{
"resetSharedKey": true
}
Durch das Zurücksetzen des Schlüssels wird die erforderliche Zwei-Faktor-Authentifizierung für den oder die authentifierende*n Benutzer*in automatisch deaktiviert, bis sie durch eine nachfolgende Anforderung reaktiviert wird.
Vergessen des Computers
Rufen Sie diesen Endpunkt auf, wobei ForgetMachine auf „true“ festgelegt sein muss, um das cookie-Flag „Anmeldedaten speichern“ zu löschen, falls vorhanden. Hier ist ein Anforderungstextbeispiel:
{
"forgetMachine": true
}
Dieser Endpunkt hat keine Auswirkungen auf die tokenbasierte Authentifizierung.
Verwenden des GET /manage/info
-Endpunkts
Dieser ruft die E-Mail-Adresse und den E-Mail-Bestätigungsstatus des oder der angemeldeten Benutzer*in ab. Ansprüche wurden aus Sicherheitsgründen bei diesem Endpunkt weggelassen. Wenn Ansprüche erforderlich sind, verwenden Sie die serverseitigen APIs, um einen Endpunkt für Ansprüche einzurichten. Statt alle Ansprüche der Benutzer*innen freizugeben, können Sie alternativ einen Überprüfungsendpunkt bereitstellen, der einen Anspruch akzeptiert, und antwortet, ob der oder die Benutzer*in über diesen verfügt.
Für die Anforderung sind keine Parameter erforderlich. Der Antworttext enthält die Eigenschaften Email und IsEmailConfirmed, wie im folgenden Beispiel gezeigt:
{
"email": "string",
"isEmailConfirmed": true
}
Verwenden des POST /manage/info
-Endpunkts
Dieser aktualisiert die E-Mail-Adresse und das Kennwort des oder der angemeldeten Benutzer*in. Übermitteln Sie NewEmail, NewPassword und OldPassword im Anforderungstext, wie im folgenden Beispiel gezeigt:
{
"newEmail": "string",
"newPassword": "string",
"oldPassword": "string"
}
Es folgt ein Beispiel für den Antworttext:
{
"email": "string",
"isEmailConfirmed": false
}
Siehe auch
Weitere Informationen finden Sie in den folgenden Ressourcen:
- Auswählen einer identity Verwaltungslösung
- Identity-Verwaltungslösungen für .NET-Web-Apps
- Einfache Autorisierung in ASP.NET Core
- Hinzufügen, Herunterladen und Löschen von Identity-Benutzerdaten in einem ASP.NET Core-Projekt
- Erstellen einer ASP.NET Core-App mit Benutzerdaten, die durch Autorisierung geschützt sind
- Account confirmation and password recovery in ASP.NET Core (Kontobestätigung und Kennwortwiederherstellung in ASP.NET Core)
- Enable QR Code generation for authenticator apps in ASP.NET Core (Aktivieren der QR-Code-Generierung für TOTP-Authentifikator-Apps in ASP.NET Core)
- Exemplarisches Web-API-Back-End für SPAs Die HTTP-Datei zeigt die tokenbasierte Authentifizierung. Beispiel:
useCookies
wird nicht festgelegt.- Das Token wird mithilfe des Autorisierungsheaders übergeben.
- Zeigt die Verlängerung der Sitzung mittels Aktualisierung, ohne eine erneute Benutzeranmeldung zu erzwingen.
- Exemplarische Angular-App, die Identity verwendet, um ein Web-API-Back-End zu schützen
Die ASP.NET Core-Vorlagen bieten eine Authentifizierung in Single-Page-Webanwendungen (SPAs) unter Verwendung der Unterstützung für die API-Autorisierung. Die ASP.NET Core Identity für die Authentifizierung und zum Speichern von Benutzer*innen wird dabei mit Duende Identity Server für die Implementierung von OpenID Connect kombiniert.
Wichtig
Duende Software erhebt ggf. eine Lizenzgebühr für die Nutzung von Duende Identity Server in der Produktion. Weitere Informationen finden Sie unter Migrieren von ASP.NET Core 5.0 zu 6.0.
Den Angular- und React-Projektvorlagen wurde ein Authentifizierungsparameter hinzugefügt, der dem Authentifizierungsparameter in den Projektvorlagen für Webanwendung (Model View Controller) (MVC) und Webanwendung (Razor Pages) ähnelt. Die zulässigen Parameterwerte sind None und Individual. Die Projektvorlage für React.js und Redux unterstützt den Authentifizierungsparameter derzeit nicht.
Erstellen einer App mit Unterstützung für die API-Autorisierung
Die Benutzerauthentifizierung und -autorisierung kann sowohl mit Angular- als auch mit React-SPAs verwendet werden. Öffnen Sie eine Befehlsshell, und führen Sie den folgenden Befehl aus:
Angular:
dotnet new angular -au Individual
React:
dotnet new react -au Individual
Mit dem obigen Befehl wird eine ASP.NET Core-App mit einem ClientApp-Verzeichnis erstellt, das die Single-Page-Webanwendung enthält.
Allgemeine Beschreibung der ASP.NET Core-Komponenten der App
In den folgenden Abschnitten werden Ergänzungen zum Projekt erläutert, wenn die Authentifizierungsunterstützung eingeschlossen wird:
Program.cs
Die folgenden Codebeispiele basieren auf dem NuGet-Paket Microsoft.AspNetCore.ApiAuthorization.IdentityServer. In den Beispielen wird die API-Authentifizierung und -Autorisierung mithilfe der Erweiterungsmethoden AddApiAuthorization und AddIdentityServerJwt konfiguriert. Projekte, die die Projektvorlagen für React- oder Angular-SPAs mit Authentifizierung verwenden, enthalten einen Verweis auf dieses Paket.
dotnet new angular -au Individual
generiert die folgende Datei 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();
Mit dem vorangehenden Code wird Folgendes konfiguriert:
Identity mit der Standardbenutzeroberfläche:
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlite(connectionString)); builder.Services.AddDatabaseDeveloperPageExceptionFilter(); builder.Services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>();
IdentityServer mit einer zusätzlichen
AddApiAuthorization
-Hilfsprogrammmethode, die ASP.NET Core-Standardkonventionen zusätzlich zu IdentityServer einrichtet:builder.Services.AddIdentityServer() .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
Authentifizierung mit einer zusätzlichen
AddIdentityServerJwt
-Hilfsprogrammmethode, die die App so konfiguriert, dass sie von IdentityServer generierte JWT-Token überprüft:builder.Services.AddAuthentication() .AddIdentityServerJwt();
Die Authentifizierungsmiddleware, die für die Überprüfung der Anforderungsanmeldeinformationen und für das Festlegen des Benutzers auf den Anforderungskontext verantwortlich ist:
app.UseAuthentication();
Die IdentityServer-Middleware, die die OpenID Connect-Endpunkte bereitstellt:
app.UseIdentityServer();
Warnung
In diesem Artikel wird die Verwendung von Verbindungszeichenfolge gezeigt. Bei einer lokalen Datenbank muss der Benutzer nicht authentifiziert werden, aber in der Produktion enthalten Verbindungszeichenfolge manchmal ein Kennwort für die Authentifizierung. Ein Ressourcenbesitzer-Kennwortanmeldeinformation (ROPC) ist ein Sicherheitsrisiko, das in Produktionsdatenbanken vermieden werden sollte. Produktions-Apps sollten den sichersten verfügbaren Ablauf für die Authentifizierung verwenden. Weitere Informationen zur Authentifizierung für Apps, die für Test- oder Produktionsumgebungen bereitgestellt werden, finden Sie unter Sichere Authentifizierungsflüsse.
Azure App Service für Linux
Geben Sie für Azure App Service-Bereitstellungen unter Linux den Aussteller explizit an:
builder.Services.Configure<JwtBearerOptions>(
IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
options.Authority = "{AUTHORITY}";
});
Im obigen Code ist der Platzhalter {AUTHORITY}
die Authority, die bei OpenID Connect-Aufrufen verwendet werden soll.
Beispiel:
options.Authority = "https://contoso-service.azurewebsites.net";
AddApiAuthorization
Diese Hilfsprogrammmethode konfiguriert IdentityServer für die Verwendung unserer unterstützten Konfiguration. IdentityServer ist ein leistungsfähiges und erweiterbares Framework für Überlegungen zum Thema „App-Sicherheit“. Dies erhöht gleichzeitig die Komplexität für die meisten gängigen Szenarien unnötig. Daher werden mehrere Konventionen und Konfigurationsoptionen bereitgestellt, die sich gut als Ausgangspunkt eignen. Wenn sich Ihre Anforderungen an die Authentifizierung ändern, bietet IdentityServer eine Vielzahl leistungsfähiger Funktionen, mit denen Sie die Authentifizierung genau an Ihre Anforderungen anpassen können.
AddIdentityServerJwt
Diese Hilfsprogrammmethode konfiguriert ein Richtlinienschema für die App als Standardauthentifizierungshandler. Die Richtlinie ist so konfiguriert, dass Identity alle an beliebige Unterpfade im Identity-URL-Raum „/Identity“ weitergeleiteten Anforderungen verarbeiten kann. JwtBearerHandler
verarbeitet alle anderen Anforderungen. Darüber hinaus registriert diese Methode eine <<ApplicationName>>API
-API-Ressource bei IdentityServer mit dem Standardbereich <<ApplicationName>>API
und konfiguriert die Middleware für JWT-Bearertoken, um von IdentityServer für die App ausgestellte Token zu überprüfen.
WeatherForecastController
Beachten Sie in der Datei, dass das auf die Klasse angewandte [Authorize]
-Attribut angibt, dass die Benutzer*innen basierend auf der Standardrichtlinie autorisiert werden müssen, um auf die Ressource zuzugreifen. Die Standardautorisierungsrichtlinie wird für die Verwendung des Standardauthentifizierungsschemas konfiguriert, das von AddIdentityServerJwt
für das oben angegebene Richtlinienschema eingerichtet wurde, sodass der mit einer solchen Hilfsmethode konfigurierte JwtBearerHandler
zum Standardhandler für Anforderungen an die App wird.
ApplicationDbContext
Beachten Sie in der Datei, dass derselbe DbContext
in Identity verwendet wird, mit der Ausnahme, dass er ApiAuthorizationDbContext
erweitert (eine stärker abgeleitete Klasse von IdentityDbContext
), um das Schema für IdentityServer einzuschließen.
Für eine vollständige Kontrolle des Datenbankschemas wird von einer der verfügbaren Identity-DbContext
-Klassen geerbt, und der Kontext wird so konfiguriert, dass er das Identity-Schema einschließt, indem builder.ConfigurePersistedGrantContext(_operationalStoreOptions.Value)
in der OnModelCreating
-Methode aufgerufen wird.
OidcConfigurationController
Beachten Sie in der Datei den Endpunkt, der für die Bereitstellung der OIDC-Parameter bereitgestellt wird, die der Client verwenden muss.
appsettings.json
In der Datei appsettings.json
im Projektstamm gibt es einen neuen Abschnitt IdentityServer
, in dem die Liste der konfigurierten Clients beschrieben wird. Im folgenden Beispiel gibt es einen einzelnen Client. Der Clientname entspricht dem App-Namen, und er wird durch Konventionen dem OAuth-ClientId
-Parameter zugeordnet. Das Profil gibt den App-Typ an, der konfiguriert wird. Es wird intern verwendet, um Konventionen zu etablieren, die den Konfigurationsprozess für den Server vereinfachen. Es sind mehrere Profile verfügbar, wie im Abschnitt Anwendungsprofile erläutert.
"IdentityServer": {
"Clients": {
"angularindividualpreview3final": {
"Profile": "IdentityServerSPA"
}
}
}
appsettings.Development.json
In der Datei appsettings.Development.json
im Projektstamm befindet sich ein Abschnitt IdentityServer
, in dem der zum Signieren von Token verwendete Schlüssel beschrieben wird. Bei der Bereitstellung in der Produktion muss ein Schlüssel zusammen mit der App bereitgestellt werden, wie im Abschnitt Bereitstellen in der Produktion erläutert.
"IdentityServer": {
"Key": {
"Type": "Development"
}
}
Allgemeine Beschreibung der Angular-App
Die Unterstützung für Authentifizierung und API-Autorisierung in der Angular-Vorlage befindet sich in einem eigenen Angular-Modul im Verzeichnis ClientApp/src/api-authorization. Das Modul besteht aus folgenden Elementen:
- 3 Komponenten:
login.component.ts
verarbeitet den Anmeldeflow der App.logout.component.ts
verarbeitet den Abmeldeflow der App.login-menu.component.ts
ist ein Widget, das einen der folgenden Linksätze anzeigt:- Benutzerprofilverwaltung und Abmeldelinks, wenn Benutzer*innen authentifiziert werden
- Registrierungs- und Anmeldelinks, wenn Benutzer*innen nicht authentifiziert werden
- Ein Routenwächter (
AuthorizeGuard
), der Routen hinzugefügt werden kann und erzwingt, dass Benutzer*innen authentifiziert werden, bevor die Route besucht wird - Ein HTTP-Interceptor (
AuthorizeInterceptor
), der das Zugriffstoken an ausgehende HTTP-Anforderungen an die API anfügt, wenn Benutzer*innen authentifiziert werden - Ein Dienst
AuthorizeService
, der die Details auf niedrigerer Ebene des Authentifizierungsprozesses verarbeitet und Informationen zu den authentifizierten Benutzer*innen für die rest App zur Nutzung verfügbar macht - Ein Angular-Modul, das Routen definiert, die den Authentifizierungskomponenten der App zugeordnet sind Es werden die Anmeldemenükomponente, der Interceptor, der Wächter und der Dienst für die Nutzung durch die rest App verfügbar gemacht.
Allgemeine Beschreibung der React-App
Die Unterstützung für die Authentifizierung und API-Autorisierung in der React-Vorlage befindet sich im Verzeichnis ClientApp/src/components/api-authorization. Sie besteht aus folgenden Elementen:
- 4 Komponenten:
Login.js
verarbeitet den Anmeldeflow der App.Logout.js
verarbeitet den Abmeldeflow der App.LoginMenu.js
ist ein Widget, das einen der folgenden Linksätze anzeigt:- Benutzerprofilverwaltung und Abmeldelinks, wenn Benutzer*innen authentifiziert werden
- Registrierungs- und Anmeldelinks, wenn Benutzer*innen nicht authentifiziert werden
AuthorizeRoute.js
ist eine Routenkomponente, für die Benutzer*innen authentifiziert werden müssen, bevor die imComponent
-Parameter angegebene Komponente gerendert wird.
- Eine exportierte
authService
-Instanz derAuthorizeService
-Klasse, die die Details auf niedrigerer Ebene des Authentifizierungsprozesses verarbeitet und Informationen zu den authentifizierten Benutzenden für den Rest der App zur Nutzung verfügbar macht
Nachdem Sie nun die wichtigsten Komponenten der Lösung kennengelernt haben, können Sie sich die einzelnen Szenarien für die App genauer ansehen.
Erzwingen der Autorisierung für eine neue API
Standardmäßig ist das System so konfiguriert, dass die Autorisierung für neue APIs problemlos erzwungen werden kann. Erstellen Sie dazu einen neuen Controller, und fügen Sie das [Authorize]
-Attribut der Controllerklasse oder einer beliebigen Aktion innerhalb des Controllers hinzu.
Anpassen des API-Authentifizierungshandlers
Um die Konfiguration des JWT-Handlers der API anzupassen, konfigurieren Sie dessen JwtBearerOptions-Instanz:
builder.Services.AddAuthentication()
.AddIdentityServerJwt();
builder.Services.Configure<JwtBearerOptions>(
IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
...
});
Der JWT-Handler der API löst Ereignisse aus, die das Steuern des Authentifizierungsprozesses mithilfe von JwtBearerEvents
ermöglichen. Um Unterstützung für die API-Autorisierung bereitzustellen, registriert AddIdentityServerJwt
seine eigenen Ereignishandler.
Um die Behandlung eines Ereignisses anzupassen, umschließen Sie den vorhandenen Ereignishandler nach Bedarf mit zusätzlicher Logik. Beispiel:
builder.Services.Configure<JwtBearerOptions>(
IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
var onTokenValidated = options.Events.OnTokenValidated;
options.Events.OnTokenValidated = async context =>
{
await onTokenValidated(context);
...
}
});
Im obigen Code wird der OnTokenValidated
-Ereignishandler durch eine benutzerdefinierte Implementierung ersetzt. Diese Implementierung führt Folgendes aus:
- Aufrufen der ursprüngliche Implementierung, die von der API-Autorisierungsunterstützung bereitgestellt wird
- Ausführen der eigenen benutzerdefinierten Logik
Schützen einer clientseitigen Route (Angular)
Der Schutz einer clientseitigen Route erfolgt durch Hinzufügen des Autorisierungswächters zur Liste der auszuführenden Wächter beim Konfigurieren einer Route. Sehen Sie sich z. B. an, wie die fetch-data
-Route innerhalb des Angular-Moduls der Haupt-App konfiguriert wird:
RouterModule.forRoot([
// ...
{ path: 'fetch-data', component: FetchDataComponent, canActivate: [AuthorizeGuard] },
])
Es ist wichtig zu erwähnen, dass der Schutz einer Route nicht den eigentlichen Endpunkt selbst schützt (auf den immer noch ein [Authorize]
-Attribut angewandt werden muss), sondern dass Benutzer*innen lediglich daran gehindert werden, zur angegebenen clientseitigen Route zu navigieren, wenn sie nicht authentifiziert sind.
Authentifizieren von API-Anforderungen (Angular)
Die Authentifizierung von Anforderungen an APIs, die zusammen mit der App gehostet werden, erfolgt automatisch mithilfe des von der App definierten Interceptors des HTTP-Clients.
Schützen einer clientseitigen Route (React)
Sie schützen eine clientseitige Route, indem Sie die AuthorizeRoute
-Komponente anstelle der einfachen Route
-Komponente verwenden. Beachten Sie beispielsweise, wie die fetch-data
-Route innerhalb der App
-Komponente konfiguriert ist:
<AuthorizeRoute path='/fetch-data' component={FetchData} />
Schützen einer Route:
- Der eigentliche Endpunkt wird nicht geschützt (auf ihn muss immer noch ein
[Authorize]
-Attribut angewandt werden). - Es wird nur verhindert, dass Benutzer*innen zur angegebenen clientseitigen Route navigieren, wenn sie nicht authentifiziert sind.
Authentifizieren von API-Anforderungen (React)
Die Authentifizierung von Anforderungen mit React erfolgt, indem zuerst die authService
-Instanz aus dem AuthorizeService
importiert wird. Das Zugriffstoken wird wie unten dargestellt von authService
abgerufen und an die Anforderung angefügt. In React-Komponenten erfolgt dieser Schritt in der Regel in der componentDidMount
-Lebenszyklusmethode oder als Ergebnis einer Benutzerinteraktion.
Importieren des authService
in eine Komponente
import authService from './api-authorization/AuthorizeService'
Abrufen und Anfügen des Zugriffstokens an die Antwort
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 });
}
Bereitstellen für die Produktion
Um die App in der Produktion bereitzustellen, müssen die folgenden Ressourcen bereitgestellt werden:
- Eine Datenbank zum Speichern der Identity-Benutzerkonten und der IdentityServer-Zuweisungen.
- Ein Produktionszertifikat zum Signieren von Token.
- Für dieses Zertifikat gibt es keine spezifischen Anforderungen. Es kann sich um ein selbstsigniertes Zertifikat oder ein Zertifikat handeln, das über eine Zertifizierungsstelle bereitgestellt wird.
- Es kann mit Standardtools wie PowerShell oder OpenSSL generiert werden.
- Es kann im Zertifikatspeicher auf den Zielcomputern installiert oder als PFX-Datei mit einem sicheren Kennwort bereitgestellt werden.
Beispiel: Bereitstellen bei einem anderen Webhostinganbieter als Azure
Erstellen Sie Ihr Zertifikat in Ihrem Webhostingbereich, oder laden Sie es. Ändern Sie dann in der Datei appsettings.json
der App den Abschnitt IdentityServer
, um Schlüsseldetails einzuschließen. Beispiel:
"IdentityServer": {
"Key": {
"Type": "Store",
"StoreName": "WebHosting",
"StoreLocation": "CurrentUser",
"Name": "CN=MyApplication"
}
}
Im vorherigen Beispiel:
StoreName
stellt den Namen des Zertifikatspeichers dar, in dem das Zertifikat gespeichert wird. In diesem Fall verweist er auf den Webhostingspeicher.StoreLocation
gibt an, von wo das Zertifikat geladen werden soll (in diesem FallCurrentUser
).Name
entspricht dem spezifischen Antragsteller des Zertifikats.
Beispiel: Bereitstellen in Azure App Service
In diesem Abschnitt wird die Bereitstellung der App für Azure App Service mithilfe eines im Zertifikatspeicher gespeicherten Zertifikats beschrieben. Um die App so zu ändern, dass sie ein Zertifikat aus dem Zertifikatspeicher lädt, ist ein Dienstplan im Tarif Standard oder höher erforderlich, wenn Sie die App in einem späteren Schritt im Azure-Portal konfigurieren.
Ändern Sie in der Datei appsettings.json
der App den Abschnitt IdentityServer
, um Schlüsseldetails einzuschließen:
"IdentityServer": {
"Key": {
"Type": "Store",
"StoreName": "My",
"StoreLocation": "CurrentUser",
"Name": "CN=MyApplication"
}
}
- Der Speichername stellt den Namen des Zertifikatspeichers dar, in dem das Zertifikat gespeichert wird. In diesem Fall verweist er auf den persönlichen Benutzerspeicher.
- Der Speicherort gibt an, von wo das Zertifikat geladen werden soll (
CurrentUser
oderLocalMachine
). - Die name-Eigenschaft des Zertifikats entspricht dem spezifischen Antragsteller des Zertifikats.
Führen Sie zum Bereitstellen in Azure App Service die Schritte unter Bereitstellen der App in Azure aus, in denen erläutert wird, wie Sie die erforderlichen Azure-Ressourcen erstellen und die App in der Produktion bereitstellen.
Nachdem Sie die obigen Anweisungen ausgeführt haben, wird die App in Azure bereitgestellt, sie ist aber noch nicht funktionsfähig. Das von der App verwendete Zertifikat muss im Azure-Portal konfiguriert werden. Suchen Sie den Fingerabdruck für das Zertifikat, und führen Sie die unter Laden Ihrer Zertifikate beschriebenen Schritte aus.
Auch wenn in diesen Schritten SSL angegeben ist, gibt es im Azure-Portal einen Bereich Private Zertifikate, in dem Sie das bereitgestellte Zertifikat für die Verwendung mit der App hochladen können.
Nachdem Sie die App und die Einstellungen der App im Azure-Portal konfiguriert haben, starten Sie die App im Portal neu.
Weitere Konfigurationsoptionen
Die Unterstützung der API-Autorisierung basiert auf IdentityServer mit einigen Konventionen, Standardwerten und Verbesserungen, um die Erfahrung für Single-Page-Webanwendungen (SPAs) zu vereinfachen. Dabei muss nicht erwähnt werden, dass die volle Leistungsfähigkeit von IdentityServer im Hintergrund verfügbar ist, wenn die ASP.NET Core-Integrationen Ihr Szenario nicht abdecken. Die ASP.NET Core-Unterstützung konzentriert sich auf „Erstanbieter“-Apps, bei denen alle Apps von uns erstellt und bereitgestellt werden. Daher wird keine Unterstützung für Aspekte wie Einwilligung oder Verbund angeboten. Verwenden Sie in solchen Szenarien IdentityServer, und befolgen Sie die entsprechende Dokumentation.
Anwendungsprofile
Anwendungsprofile sind vordefinierte Konfigurationen für Apps, die ihre Parameter genauer definieren. Derzeit werden die folgenden Profile unterstützt:
IdentityServerSPA
: stellt eine SPA dar, die zusammen mit IdentityServer als einzelne Einheit gehostet wird.- Der Standardwert von
redirect_uri
lautet/authentication/login-callback
. - Der Standardwert von
post_logout_redirect_uri
lautet/authentication/logout-callback
. - Zu den Bereichen gehören
openid
,profile
und alle Bereiche, die in der App für die APIs definiert sind. - Die zulässigen OIDC-Antworttypen sind
id_token token
oder jeder einzelne Typ (id_token
,token
). - Der zulässige Antwortmodus ist
fragment
.
- Der Standardwert von
SPA
: stellt eine Single-Page-Webanwendung dar, die nicht mit IdentityServer gehostet wird.- Zu den Bereichen gehören
openid
,profile
und alle Bereiche, die in der App für die APIs definiert sind. - Die zulässigen OIDC-Antworttypen sind
id_token token
oder jeder einzelne Typ (id_token
,token
). - Der zulässige Antwortmodus ist
fragment
.
- Zu den Bereichen gehören
IdentityServerJwt
: stellt eine API dar, die mit IdentityServer gehostet wird.- Die App ist so konfiguriert, dass sie über einen einzelnen Bereich verfügt, der standardmäßig auf den App-Namen festgelegt ist.
API
: stellt eine API dar, die nicht zusammen mit IdentityServer gehostet wird.- Die App ist so konfiguriert, dass sie über einen einzelnen Bereich verfügt, der standardmäßig auf den App-Namen festgelegt ist.
Konfigurieren über AppSettings
Konfigurieren Sie die Apps über das Konfigurationssystem, indem Sie sie der Liste von Clients
oder Resources
hinzufügen.
Konfigurieren Sie die Eigenschaften redirect_uri
und post_logout_redirect_uri
der einzelnen Clients, wie im folgenden Beispiel gezeigt:
"IdentityServer": {
"Clients": {
"MySPA": {
"Profile": "SPA",
"RedirectUri": "https://www.example.com/authentication/login-callback",
"LogoutUri": "https://www.example.com/authentication/logout-callback"
}
}
}
Beim Konfigurieren von Ressourcen können Sie die Bereiche für eine Ressource wie unten gezeigt konfigurieren:
"IdentityServer": {
"Resources": {
"MyExternalApi": {
"Profile": "API",
"Scopes": "a b c"
}
}
}
Konfigurieren über Code
Sie können die Clients und Ressourcen auch im Code konfigurieren, indem Sie eine Überladung von AddApiAuthorization
verwenden, die eine Aktion zum Konfigurieren von Optionen ausführt.
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"));
});
Zusätzliche Ressourcen
Die Vorlagen von ASP.NET Core 3.1 und höher bieten eine Authentifizierung in Single-Page-Webanwendungen (SPAs) unter Verwendung der Unterstützung für die API-Autorisierung. Die ASP.NET Core Identity für die Authentifizierung und zum Speichern von Benutzenden wird mit IdentityServer für die Implementierung von Open ID Connect kombiniert.
Den Angular- und React-Projektvorlagen wurde ein Authentifizierungsparameter hinzugefügt, der dem Authentifizierungsparameter in den Projektvorlagen für Webanwendung (Model View Controller) (MVC) und Webanwendung (Razor Pages) ähnelt. Die zulässigen Parameterwerte sind None und Individual. Die Projektvorlage für React.js und Redux unterstützt den Authentifizierungsparameter derzeit nicht.
Erstellen einer App mit Unterstützung für die API-Autorisierung
Die Benutzerauthentifizierung und -autorisierung kann sowohl mit Angular- als auch mit React-SPAs verwendet werden. Öffnen Sie eine Befehlsshell, und führen Sie den folgenden Befehl aus:
Angular:
dotnet new angular -o <output_directory_name>
React:
dotnet new react -o <output_directory_name> -au Individual
Mit dem obigen Befehl wird eine ASP.NET Core-App mit einem ClientApp-Verzeichnis erstellt, das die Single-Page-Webanwendung enthält.
Allgemeine Beschreibung der ASP.NET Core-Komponenten der App
In den folgenden Abschnitten werden Ergänzungen zum Projekt erläutert, wenn die Authentifizierungsunterstützung eingeschlossen wird:
Startup
-Klasse
Die folgenden Codebeispiele basieren auf dem NuGet-Paket Microsoft.AspNetCore.ApiAuthorization.IdentityServer. In den Beispielen wird die API-Authentifizierung und -Autorisierung mithilfe der Erweiterungsmethoden AddApiAuthorization und AddIdentityServerJwt konfiguriert. Projekte, die die Projektvorlagen für React- oder Angular-SPAs mit Authentifizierung verwenden, enthalten einen Verweis auf dieses Paket.
Die Startup
-Klasse verfügt über die folgenden Ergänzungen:
Innerhalb der
Startup.ConfigureServices
-Methode:Identity mit der Standardbenutzeroberfläche:
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlite(Configuration.GetConnectionString("DefaultConnection"))); services.AddDefaultIdentity<ApplicationUser>() .AddEntityFrameworkStores<ApplicationDbContext>();
IdentityServer mit einer zusätzlichen
AddApiAuthorization
-Hilfsprogrammmethode, die ASP.NET Core-Standardkonventionen zusätzlich zu IdentityServer einrichtet:services.AddIdentityServer() .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
Authentifizierung mit einer zusätzlichen
AddIdentityServerJwt
-Hilfsprogrammmethode, die die App so konfiguriert, dass sie von IdentityServer generierte JWT-Token überprüft:services.AddAuthentication() .AddIdentityServerJwt();
Innerhalb der
Startup.Configure
-Methode:Die Authentifizierungsmiddleware, die für die Überprüfung der Anforderungsanmeldeinformationen und für das Festlegen des Benutzers auf den Anforderungskontext verantwortlich ist:
app.UseAuthentication();
Die IdentityServer-Middleware, die die OpenID Connect-Endpunkte bereitstellt:
app.UseIdentityServer();
Warnung
In diesem Artikel wird die Verwendung von Verbindungszeichenfolge gezeigt. Bei einer lokalen Datenbank muss der Benutzer nicht authentifiziert werden, aber in der Produktion enthalten Verbindungszeichenfolge manchmal ein Kennwort für die Authentifizierung. Ein Ressourcenbesitzer-Kennwortanmeldeinformation (ROPC) ist ein Sicherheitsrisiko, das in Produktionsdatenbanken vermieden werden sollte. Produktions-Apps sollten den sichersten verfügbaren Ablauf für die Authentifizierung verwenden. Weitere Informationen zur Authentifizierung für Apps, die für Test- oder Produktionsumgebungen bereitgestellt werden, finden Sie unter Sichere Authentifizierungsflüsse.
Azure App Service für Linux
Geben Sie für Azure App Service-Bereitstellungen unter Linux den Aussteller explizit in Startup.ConfigureServices
an:
services.Configure<JwtBearerOptions>(
IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
options.Authority = "{AUTHORITY}";
});
Im obigen Code ist der Platzhalter {AUTHORITY}
die Authority, die bei OpenID Connect-Aufrufen verwendet werden soll.
Beispiel:
options.Authority = "https://contoso-service.azurewebsites.net";
AddApiAuthorization
Diese Hilfsprogrammmethode konfiguriert IdentityServer für die Verwendung unserer unterstützten Konfiguration. IdentityServer ist ein leistungsfähiges und erweiterbares Framework für Überlegungen zum Thema „App-Sicherheit“. Dies erhöht gleichzeitig die Komplexität für die meisten gängigen Szenarien unnötig. Daher werden mehrere Konventionen und Konfigurationsoptionen bereitgestellt, die sich gut als Ausgangspunkt eignen. Wenn sich Ihre Anforderungen an die Authentifizierung ändern, bietet IdentityServer eine Vielzahl leistungsfähiger Funktionen, mit denen Sie die Authentifizierung genau an Ihre Anforderungen anpassen können.
AddIdentityServerJwt
Diese Hilfsprogrammmethode konfiguriert ein Richtlinienschema für die App als Standardauthentifizierungshandler. Die Richtlinie ist so konfiguriert, dass Identity alle an beliebige Unterpfade im Identity-URL-Raum „/Identity“ weitergeleiteten Anforderungen verarbeiten kann. JwtBearerHandler
verarbeitet alle anderen Anforderungen. Darüber hinaus registriert diese Methode eine <<ApplicationName>>API
-API-Ressource bei IdentityServer mit dem Standardbereich <<ApplicationName>>API
und konfiguriert die Middleware für JWT-Bearertoken, um von IdentityServer für die App ausgestellte Token zu überprüfen.
WeatherForecastController
Beachten Sie in der Datei, dass das auf die Klasse angewandte [Authorize]
-Attribut angibt, dass die Benutzer*innen basierend auf der Standardrichtlinie autorisiert werden müssen, um auf die Ressource zuzugreifen. Die Standardautorisierungsrichtlinie wird für die Verwendung des Standardauthentifizierungsschemas konfiguriert, das von AddIdentityServerJwt
für das oben angegebene Richtlinienschema eingerichtet wurde, sodass der mit einer solchen Hilfsmethode konfigurierte JwtBearerHandler
zum Standardhandler für Anforderungen an die App wird.
ApplicationDbContext
Beachten Sie in der Datei, dass derselbe DbContext
in Identity verwendet wird, mit der Ausnahme, dass er ApiAuthorizationDbContext
erweitert (eine stärker abgeleitete Klasse von IdentityDbContext
), um das Schema für IdentityServer einzuschließen.
Für eine vollständige Kontrolle des Datenbankschemas wird von einer der verfügbaren Identity-DbContext
-Klassen geerbt, und der Kontext wird so konfiguriert, dass er das Identity-Schema einschließt, indem builder.ConfigurePersistedGrantContext(_operationalStoreOptions.Value)
in der OnModelCreating
-Methode aufgerufen wird.
OidcConfigurationController
Beachten Sie in der Datei den Endpunkt, der für die Bereitstellung der OIDC-Parameter bereitgestellt wird, die der Client verwenden muss.
appsettings.json
In der Datei appsettings.json
im Projektstamm gibt es einen neuen Abschnitt IdentityServer
, in dem die Liste der konfigurierten Clients beschrieben wird. Im folgenden Beispiel gibt es einen einzelnen Client. Der Clientname entspricht dem App-Namen, und er wird durch Konventionen dem OAuth-ClientId
-Parameter zugeordnet. Das Profil gibt den App-Typ an, der konfiguriert wird. Es wird intern verwendet, um Konventionen zu etablieren, die den Konfigurationsprozess für den Server vereinfachen. Es sind mehrere Profile verfügbar, wie im Abschnitt Anwendungsprofile erläutert.
"IdentityServer": {
"Clients": {
"angularindividualpreview3final": {
"Profile": "IdentityServerSPA"
}
}
}
appsettings.Development.json
In der Datei appsettings.Development.json
im Projektstamm befindet sich ein Abschnitt IdentityServer
, in dem der zum Signieren von Token verwendete Schlüssel beschrieben wird. Bei der Bereitstellung in der Produktion muss ein Schlüssel zusammen mit der App bereitgestellt werden, wie im Abschnitt Bereitstellen in der Produktion erläutert.
"IdentityServer": {
"Key": {
"Type": "Development"
}
}
Allgemeine Beschreibung der Angular-App
Die Unterstützung für Authentifizierung und API-Autorisierung in der Angular-Vorlage befindet sich in einem eigenen Angular-Modul im Verzeichnis ClientApp/src/api-authorization. Das Modul besteht aus folgenden Elementen:
- 3 Komponenten:
login.component.ts
verarbeitet den Anmeldeflow der App.logout.component.ts
verarbeitet den Abmeldeflow der App.login-menu.component.ts
ist ein Widget, das einen der folgenden Linksätze anzeigt:- Benutzerprofilverwaltung und Abmeldelinks, wenn Benutzer*innen authentifiziert werden
- Registrierungs- und Anmeldelinks, wenn Benutzer*innen nicht authentifiziert werden
- Ein Routenwächter (
AuthorizeGuard
), der Routen hinzugefügt werden kann und erzwingt, dass Benutzer*innen authentifiziert werden, bevor die Route besucht wird - Ein HTTP-Interceptor (
AuthorizeInterceptor
), der das Zugriffstoken an ausgehende HTTP-Anforderungen an die API anfügt, wenn Benutzer*innen authentifiziert werden - Ein Dienst
AuthorizeService
, der die Details auf niedrigerer Ebene des Authentifizierungsprozesses verarbeitet und Informationen zu den authentifizierten Benutzer*innen für die rest App zur Nutzung verfügbar macht - Ein Angular-Modul, das Routen definiert, die den Authentifizierungskomponenten der App zugeordnet sind Es werden die Anmeldemenükomponente, der Interceptor, der Wächter und der Dienst für die Nutzung durch die rest App verfügbar gemacht.
Allgemeine Beschreibung der React-App
Die Unterstützung für die Authentifizierung und API-Autorisierung in der React-Vorlage befindet sich im Verzeichnis ClientApp/src/components/api-authorization. Sie besteht aus folgenden Elementen:
- 4 Komponenten:
Login.js
verarbeitet den Anmeldeflow der App.Logout.js
verarbeitet den Abmeldeflow der App.LoginMenu.js
ist ein Widget, das einen der folgenden Linksätze anzeigt:- Benutzerprofilverwaltung und Abmeldelinks, wenn Benutzer*innen authentifiziert werden
- Registrierungs- und Anmeldelinks, wenn Benutzer*innen nicht authentifiziert werden
AuthorizeRoute.js
ist eine Routenkomponente, für die Benutzer*innen authentifiziert werden müssen, bevor die imComponent
-Parameter angegebene Komponente gerendert wird.
- Eine exportierte
authService
-Instanz derAuthorizeService
-Klasse, die die Details auf niedrigerer Ebene des Authentifizierungsprozesses verarbeitet und Informationen zu den authentifizierten Benutzenden für den Rest der App zur Nutzung verfügbar macht
Nachdem Sie nun die wichtigsten Komponenten der Lösung kennengelernt haben, können Sie sich die einzelnen Szenarien für die App genauer ansehen.
Erzwingen der Autorisierung für eine neue API
Standardmäßig ist das System so konfiguriert, dass die Autorisierung für neue APIs problemlos erzwungen werden kann. Erstellen Sie dazu einen neuen Controller, und fügen Sie das [Authorize]
-Attribut der Controllerklasse oder einer beliebigen Aktion innerhalb des Controllers hinzu.
Anpassen des API-Authentifizierungshandlers
Um die Konfiguration des JWT-Handlers der API anzupassen, konfigurieren Sie dessen JwtBearerOptions-Instanz:
services.AddAuthentication()
.AddIdentityServerJwt();
services.Configure<JwtBearerOptions>(
IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
...
});
Der JWT-Handler der API löst Ereignisse aus, die das Steuern des Authentifizierungsprozesses mithilfe von JwtBearerEvents
ermöglichen. Um Unterstützung für die API-Autorisierung bereitzustellen, registriert AddIdentityServerJwt
seine eigenen Ereignishandler.
Um die Behandlung eines Ereignisses anzupassen, umschließen Sie den vorhandenen Ereignishandler nach Bedarf mit zusätzlicher Logik. Beispiel:
services.Configure<JwtBearerOptions>(
IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
var onTokenValidated = options.Events.OnTokenValidated;
options.Events.OnTokenValidated = async context =>
{
await onTokenValidated(context);
...
}
});
Im obigen Code wird der OnTokenValidated
-Ereignishandler durch eine benutzerdefinierte Implementierung ersetzt. Diese Implementierung führt Folgendes aus:
- Aufrufen der ursprüngliche Implementierung, die von der API-Autorisierungsunterstützung bereitgestellt wird
- Ausführen der eigenen benutzerdefinierten Logik
Schützen einer clientseitigen Route (Angular)
Der Schutz einer clientseitigen Route erfolgt durch Hinzufügen des Autorisierungswächters zur Liste der auszuführenden Wächter beim Konfigurieren einer Route. Sehen Sie sich z. B. an, wie die fetch-data
-Route innerhalb des Angular-Moduls der Haupt-App konfiguriert wird:
RouterModule.forRoot([
// ...
{ path: 'fetch-data', component: FetchDataComponent, canActivate: [AuthorizeGuard] },
])
Es ist wichtig zu erwähnen, dass der Schutz einer Route nicht den eigentlichen Endpunkt selbst schützt (auf den immer noch ein [Authorize]
-Attribut angewandt werden muss), sondern dass Benutzer*innen lediglich daran gehindert werden, zur angegebenen clientseitigen Route zu navigieren, wenn sie nicht authentifiziert sind.
Authentifizieren von API-Anforderungen (Angular)
Die Authentifizierung von Anforderungen an APIs, die zusammen mit der App gehostet werden, erfolgt automatisch mithilfe des von der App definierten Interceptors des HTTP-Clients.
Schützen einer clientseitigen Route (React)
Sie schützen eine clientseitige Route, indem Sie die AuthorizeRoute
-Komponente anstelle der einfachen Route
-Komponente verwenden. Beachten Sie beispielsweise, wie die fetch-data
-Route innerhalb der App
-Komponente konfiguriert ist:
<AuthorizeRoute path='/fetch-data' component={FetchData} />
Schützen einer Route:
- Der eigentliche Endpunkt wird nicht geschützt (auf ihn muss immer noch ein
[Authorize]
-Attribut angewandt werden). - Es wird nur verhindert, dass Benutzer*innen zur angegebenen clientseitigen Route navigieren, wenn sie nicht authentifiziert sind.
Authentifizieren von API-Anforderungen (React)
Die Authentifizierung von Anforderungen mit React erfolgt, indem zuerst die authService
-Instanz aus dem AuthorizeService
importiert wird. Das Zugriffstoken wird wie unten dargestellt von authService
abgerufen und an die Anforderung angefügt. In React-Komponenten erfolgt dieser Schritt in der Regel in der componentDidMount
-Lebenszyklusmethode oder als Ergebnis einer Benutzerinteraktion.
Importieren des authService
in eine Komponente
import authService from './api-authorization/AuthorizeService'
Abrufen und Anfügen des Zugriffstokens an die Antwort
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 });
}
Bereitstellen für die Produktion
Um die App in der Produktion bereitzustellen, müssen die folgenden Ressourcen bereitgestellt werden:
- Eine Datenbank zum Speichern der Identity-Benutzerkonten und der IdentityServer-Zuweisungen.
- Ein Produktionszertifikat zum Signieren von Token.
- Für dieses Zertifikat gibt es keine spezifischen Anforderungen. Es kann sich um ein selbstsigniertes Zertifikat oder ein Zertifikat handeln, das über eine Zertifizierungsstelle bereitgestellt wird.
- Es kann mit Standardtools wie PowerShell oder OpenSSL generiert werden.
- Es kann im Zertifikatspeicher auf den Zielcomputern installiert oder als PFX-Datei mit einem sicheren Kennwort bereitgestellt werden.
Beispiel: Bereitstellen bei einem anderen Webhostinganbieter als Azure
Erstellen Sie Ihr Zertifikat in Ihrem Webhostingbereich, oder laden Sie es. Ändern Sie dann in der Datei appsettings.json
der App den Abschnitt IdentityServer
, um Schlüsseldetails einzuschließen. Beispiel:
"IdentityServer": {
"Key": {
"Type": "Store",
"StoreName": "WebHosting",
"StoreLocation": "CurrentUser",
"Name": "CN=MyApplication"
}
}
Im vorherigen Beispiel:
StoreName
stellt den Namen des Zertifikatspeichers dar, in dem das Zertifikat gespeichert wird. In diesem Fall verweist er auf den Webhostingspeicher.StoreLocation
gibt an, von wo das Zertifikat geladen werden soll (in diesem FallCurrentUser
).Name
entspricht dem spezifischen Antragsteller des Zertifikats.
Beispiel: Bereitstellen in Azure App Service
In diesem Abschnitt wird die Bereitstellung der App für Azure App Service mithilfe eines im Zertifikatspeicher gespeicherten Zertifikats beschrieben. Um die App so zu ändern, dass sie ein Zertifikat aus dem Zertifikatspeicher lädt, ist ein Dienstplan im Tarif Standard oder höher erforderlich, wenn Sie die App in einem späteren Schritt im Azure-Portal konfigurieren.
Ändern Sie in der Datei appsettings.json
der App den Abschnitt IdentityServer
, um Schlüsseldetails einzuschließen:
"IdentityServer": {
"Key": {
"Type": "Store",
"StoreName": "My",
"StoreLocation": "CurrentUser",
"Name": "CN=MyApplication"
}
}
- Der Speichername stellt den Namen des Zertifikatspeichers dar, in dem das Zertifikat gespeichert wird. In diesem Fall verweist er auf den persönlichen Benutzerspeicher.
- Der Speicherort gibt an, von wo das Zertifikat geladen werden soll (
CurrentUser
oderLocalMachine
). - Die name-Eigenschaft des Zertifikats entspricht dem spezifischen Antragsteller des Zertifikats.
Führen Sie zum Bereitstellen in Azure App Service die Schritte unter Bereitstellen der App in Azure aus, in denen erläutert wird, wie Sie die erforderlichen Azure-Ressourcen erstellen und die App in der Produktion bereitstellen.
Nachdem Sie die obigen Anweisungen ausgeführt haben, wird die App in Azure bereitgestellt, sie ist aber noch nicht funktionsfähig. Das von der App verwendete Zertifikat muss im Azure-Portal konfiguriert werden. Suchen Sie den Fingerabdruck für das Zertifikat, und führen Sie die unter Laden Ihrer Zertifikate beschriebenen Schritte aus.
Auch wenn in diesen Schritten SSL angegeben ist, gibt es im Azure-Portal einen Bereich Private Zertifikate, in dem Sie das bereitgestellte Zertifikat für die Verwendung mit der App hochladen können.
Nachdem Sie die App und die Einstellungen der App im Azure-Portal konfiguriert haben, starten Sie die App im Portal neu.
Weitere Konfigurationsoptionen
Die Unterstützung der API-Autorisierung basiert auf IdentityServer mit einigen Konventionen, Standardwerten und Verbesserungen, um die Erfahrung für Single-Page-Webanwendungen (SPAs) zu vereinfachen. Dabei muss nicht erwähnt werden, dass die volle Leistungsfähigkeit von IdentityServer im Hintergrund verfügbar ist, wenn die ASP.NET Core-Integrationen Ihr Szenario nicht abdecken. Die ASP.NET Core-Unterstützung konzentriert sich auf „Erstanbieter“-Apps, bei denen alle Apps von uns erstellt und bereitgestellt werden. Daher wird keine Unterstützung für Aspekte wie Einwilligung oder Verbund angeboten. Verwenden Sie in solchen Szenarien IdentityServer, und befolgen Sie die entsprechende Dokumentation.
Anwendungsprofile
Anwendungsprofile sind vordefinierte Konfigurationen für Apps, die ihre Parameter genauer definieren. Derzeit werden die folgenden Profile unterstützt:
IdentityServerSPA
: stellt eine SPA dar, die zusammen mit IdentityServer als einzelne Einheit gehostet wird.- Der Standardwert von
redirect_uri
lautet/authentication/login-callback
. - Der Standardwert von
post_logout_redirect_uri
lautet/authentication/logout-callback
. - Zu den Bereichen gehören
openid
,profile
und alle Bereiche, die in der App für die APIs definiert sind. - Die zulässigen OIDC-Antworttypen sind
id_token token
oder jeder einzelne Typ (id_token
,token
). - Der zulässige Antwortmodus ist
fragment
.
- Der Standardwert von
SPA
: stellt eine Single-Page-Webanwendung dar, die nicht mit IdentityServer gehostet wird.- Zu den Bereichen gehören
openid
,profile
und alle Bereiche, die in der App für die APIs definiert sind. - Die zulässigen OIDC-Antworttypen sind
id_token token
oder jeder einzelne Typ (id_token
,token
). - Der zulässige Antwortmodus ist
fragment
.
- Zu den Bereichen gehören
IdentityServerJwt
: stellt eine API dar, die mit IdentityServer gehostet wird.- Die App ist so konfiguriert, dass sie über einen einzelnen Bereich verfügt, der standardmäßig auf den App-Namen festgelegt ist.
API
: stellt eine API dar, die nicht zusammen mit IdentityServer gehostet wird.- Die App ist so konfiguriert, dass sie über einen einzelnen Bereich verfügt, der standardmäßig auf den App-Namen festgelegt ist.
Konfigurieren über AppSettings
Konfigurieren Sie die Apps über das Konfigurationssystem, indem Sie sie der Liste von Clients
oder Resources
hinzufügen.
Konfigurieren Sie die Eigenschaften redirect_uri
und post_logout_redirect_uri
der einzelnen Clients, wie im folgenden Beispiel gezeigt:
"IdentityServer": {
"Clients": {
"MySPA": {
"Profile": "SPA",
"RedirectUri": "https://www.example.com/authentication/login-callback",
"LogoutUri": "https://www.example.com/authentication/logout-callback"
}
}
}
Beim Konfigurieren von Ressourcen können Sie die Bereiche für eine Ressource wie unten gezeigt konfigurieren:
"IdentityServer": {
"Resources": {
"MyExternalApi": {
"Profile": "API",
"Scopes": "a b c"
}
}
}
Konfigurieren über Code
Sie können die Clients und Ressourcen auch im Code konfigurieren, indem Sie eine Überladung von AddApiAuthorization
verwenden, die eine Aktion zum Konfigurieren von Optionen ausführt.
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"));
});