Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Gilt für: Mitarbeitermandanten
Externe Mandanten (weitere Informationen)
In dieser Lernprogrammreihe wird veranschaulicht, wie Sie eine ASP.NET Core-Web-API mit der Microsoft Identity Platform schützen, um den Zugriff auf autorisierte Benutzer und Client-Apps zu beschränken. Die web-API, die Sie erstellen, verwendet sowohl delegierte Berechtigungen (Bereiche) als auch Anwendungsberechtigungen (App-Rollen).
In diesem Tutorial führen Sie Folgendes durch:
- Erstellen einer ASP.NET Core-Web-API
- Konfigurieren der Web-API für die Verwendung der Registrierungsdetails der Microsoft Entra-App
- Schützen Ihrer Web-API-Endpunkte
- Führen Sie die Web-API aus, um sicherzustellen, dass sie HTTP-Anforderungen überwacht
Voraussetzungen
- Falls noch nicht geschehen, führen Sie die Schritte in der Schnellstartanleitung aus: Aufrufen einer Web-API, die durch die Microsoft Identity Platform geschützt ist. Sie müssen das Codebeispiel nicht klonen und ausführen, stellen Sie jedoch sicher, dass Sie folgendes haben:
- Die App-Registrierungsdetails der Web-API aus dem Microsoft Entra Admin-Center, einschließlich Client-ID und Mandanten-ID.
- ToDoList.Read und ToDoList.ReadWrite als delegierte Berechtigungen (Bereiche), die von der Web-API verfügbar gemacht werden
- ToDoList.Read.All und ToDoList.ReadWrite.All als Anwendungsberechtigungen (App-Rollen), die von der Web-API verfügbar gemacht werden
- .NET 8.0 SDK oder höher.
- Visual Studio Code oder ein anderer Code-Editor.
Erstellen eines neuen ASP.NET Core-Web-API-Projekts
Führen Sie die folgenden Schritte aus, um ein minimales ASP.NET Core-Web-API-Projekt zu erstellen:
Öffnen Sie Ihr Terminal in Visual Studio Code oder einem anderen Code-Editor, und navigieren Sie zu dem Verzeichnis, in dem Sie Ihr Projekt erstellen möchten.
Führen Sie die folgenden Befehle auf der .NET CLI oder einem anderen Befehlszeilentool aus.
dotnet new web -o TodoListApi cd TodoListApi
Wählen Sie "Ja " aus, wenn ein Dialogfeld fragt, ob Sie den Autoren vertrauen möchten.
Wählen Sie "Ja " aus, wenn ein Dialogfeld fragt, ob Sie dem Projekt erforderliche Ressourcen hinzufügen möchten.
Installieren Sie die erforderlichen Pakete
Um die ASP.NET Core-Web-API zu erstellen, zu schützen und zu testen, müssen Sie die folgenden Pakete installieren:
Microsoft.EntityFrameworkCore.InMemory
– Ein Paket, mit dem Sie Entity Framework Core mit einer In-Memory-Datenbank verwenden können. Es ist nützlich für Testzwecke, ist aber nicht für den Produktionseinsatz konzipiert.Microsoft.Identity.Web
– eine Reihe von ASP.NET Core-Bibliotheken, die das Hinzufügen von Authentifizierungs- und Autorisierungsunterstützung zu Web-Apps und Web-APIs vereinfachen, die in die Microsoft Identity Platform integriert werden.
Verwenden Sie folgendes, um das Paket zu installieren:
dotnet add package Microsoft.EntityFrameworkCore.InMemory
dotnet add package Microsoft.Identity.Web
Konfigurieren von Anwendungsregistrierungsdetails
Öffnen Sie die dateiappsettings.json in Ihrem App-Ordner, und fügen Sie die App-Registrierungsdetails hinzu, die Sie nach der Registrierung der Web-API aufgezeichnet haben.
{
"AzureAd": {
"Instance": "Enter_the_Authority_URL_Here",
"TenantId": "Enter_the_Tenant_Id_Here",
"ClientId": "Enter_the_Application_Id_Here"
},
"Logging": {...},
"AllowedHosts": "*"
}
Ersetzen Sie die folgenden Platzhalter wie gezeigt:
- Ersetzen Sie
Enter_the_Application_Id_Here
durch Ihre Anwendungs-ID (Client-ID). - Ersetzen Sie
Enter_the_Tenant_Id_Here
durch Ihre Verzeichnis-ID (Mandanten-ID). - Ersetzen Sie
Enter_the_Authority_URL_Here
durch Ihre Autoritäts-URL, wie im nächsten Abschnitt erläutert.
Autoritäts-URL für Ihre App
Die Autoritäts-URL gibt das Verzeichnis an, aus dem die Microsoft-Authentifizierungsbibliothek (MSAL) Token anfordern kann. Sie entwickeln es sowohl für das Personal als auch für externe Mieter auf unterschiedliche Weise, wie gezeigt:
//Instance for workforce tenant
Instance: "https://login.microsoftonline.com/"
Verwenden einer benutzerdefinierten URL-Domäne (optional)
Benutzerdefinierte URL-Domänen werden in Mitarbeitermandanten nicht unterstützt.
Berechtigungen hinzufügen
Alle APIs müssen mindestens einen Bereich (auch „delegierte Berechtigung“ genannt) veröffentlichen, damit die Clientanwendungen erfolgreich ein Zugriffstoken für Benutzer*innen abrufen können. APIs sollten auch mindestens eine App-Rolle veröffentlichen, die auch als Anwendungsberechtigungen bezeichnet wird, damit die Client-Apps ein Zugriffstoken im eigenen Namen abrufen, also dann, wenn sie keinen Benutzer anmelden.
Wir geben diese Berechtigungen in der Datei appsettings.json an. In diesem Tutorial haben Sie die folgenden delegierten und Anwendungsberechtigungen registriert:
- Delegierte Berechtigungen:ToDoList.Read und ToDoList.ReadWrite.
- Anwendungsberechtigungen:ToDoList.Read.All und ToDoList.ReadWrite.All.
Wenn ein Benutzer oder eine Clientanwendung die Web-API aufruft, werden nur Clients mit diesen Bereichen oder Berechtigungen für den Zugriff auf den geschützten Endpunkt autorisiert.
{
"AzureAd": {
"Instance": "Enter_the_Authority_URL_Here",
"TenantId": "Enter_the_Tenant_Id_Here",
"ClientId": "Enter_the_Application_Id_Here",
"Scopes": {
"Read": ["ToDoList.Read", "ToDoList.ReadWrite"],
"Write": ["ToDoList.ReadWrite"]
},
"AppPermissions": {
"Read": ["ToDoList.Read.All", "ToDoList.ReadWrite.All"],
"Write": ["ToDoList.ReadWrite.All"]
}
},
"Logging": {...},
"AllowedHosts": "*"
}
Implementieren von Authentifizierung und Autorisierung in der API
Um die Authentifizierung und Autorisierung zu konfigurieren, öffnen Sie die program.cs
Datei, und ersetzen Sie deren Inhalt durch die folgenden Codeausschnitte:
Hinzufügen eines Authentifizierungsschemas
In dieser API verwenden wir das JSON Web Token (JWT)-Bearerschema als Standardauthentifizierungsmechanismus. Verwenden Sie die AddAuthentication
Methode, um das JWT-Bearerschema zu registrieren.
// Add required packages to your imports
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
// Add an authentication scheme
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration);
Erstellen des App-Modells
Erstellen Sie im Stammordner des Projekts einen Ordner namens "Models". Navigieren Sie zum Ordner "Models ", und erstellen Sie eine Datei mit dem Namen ToDo.cs
, und fügen Sie dann den folgenden Code hinzu.
using System;
namespace ToDoListAPI.Models;
public class ToDo
{
public int Id { get; set; }
public Guid Owner { get; set; }
public string Description { get; set; } = string.Empty;
}
Der vorangehende Code erstellt ein Modell namens ToDo. Dieses Modell stellt Daten dar, die die App verwaltet.
Hinzufügen eines Datenbankkontexts
Als Nächstes definieren wir eine Datenbankkontextklasse, die die Entity Framework-Funktionalität für ein Datenmodell koordiniert. Diese Klasse erbt von der Microsoft.EntityFrameworkCore.DbContext-Klasse , die Interaktionen zwischen der Anwendung und der Datenbank verwaltet. Führen Sie die folgenden Schritte aus, um den Datenbankkontext hinzuzufügen:
Erstellen Sie einen Ordner namens "DbContext" im Stammordner Ihres Projekts.
Navigieren Sie in den DbContext-Ordner , und erstellen Sie eine Datei mit dem Namen
ToDoContext.cs
, und fügen Sie dann den folgenden Code hinzu:using Microsoft.EntityFrameworkCore; using ToDoListAPI.Models; namespace ToDoListAPI.Context; public class ToDoContext : DbContext { public ToDoContext(DbContextOptions<ToDoContext> options) : base(options) { } public DbSet<ToDo> ToDos { get; set; } }
Öffnen Sie die Program.cs Datei im Stammordner Ihres Projekts, und aktualisieren Sie sie mit dem folgenden Code:
// Add the following to your imports using ToDoListAPI.Context; using Microsoft.EntityFrameworkCore; //Register ToDoContext as a service in the application builder.Services.AddDbContext<ToDoContext>(opt => opt.UseInMemoryDatabase("ToDos"));
Im vorherigen Codeausschnitt registrieren wir DB-Kontext als bereichsbezogenen Dienst im ASP.NET Core-Anwendungsdienstanbieter (auch bekannt als Abhängigkeitseinfügungscontainer). Außerdem konfigurieren Sie die ToDoContext
Klasse für die Verwendung einer In-Memory-Datenbank für die ToDo-Listen-API.
Einrichten eines Controllers
Controller implementieren in der Regel CruD-Aktionen (Create, Read, Update, Delete) zum Verwalten von Ressourcen. Da sich dieses Lernprogramm stärker auf den Schutz der API-Endpunkte konzentriert, implementieren wir nur zwei Aktionselemente im Controller. Eine "Alle lesen"-Aktion, um alle To-Do-Elemente abzurufen, und eine Erstellen-Aktion, um ein neues To-Do-Element hinzuzufügen. Führen Sie die folgenden Schritte aus, um Ihrem Projekt einen Controller hinzuzufügen:
Navigieren Sie zum Stammordner Ihres Projekts, und erstellen Sie einen Ordner mit dem Namen "Controller".
Erstellen Sie eine Datei
ToDoListController.cs
namens im Ordner "Controller ", und fügen Sie den folgenden Code für die Kesselplatte hinzu:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.Resource;
using ToDoListAPI.Models;
using ToDoListAPI.Context;
namespace ToDoListAPI.Controllers;
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class ToDoListController : ControllerBase
{
private readonly ToDoContext _toDoContext;
public ToDoListController(ToDoContext toDoContext)
{
_toDoContext = toDoContext;
}
[HttpGet()]
[RequiredScopeOrAppPermission()]
public async Task<IActionResult> GetAsync(){...}
[HttpPost]
[RequiredScopeOrAppPermission()]
public async Task<IActionResult> PostAsync([FromBody] ToDo toDo){...}
private bool RequestCanAccessToDo(Guid userId){...}
private Guid GetUserId(){...}
private bool IsAppMakingRequest(){...}
}
Hinzufügen von Code zum Controller
In diesem Abschnitt wird erläutert, wie Sie code zum Controllergerüst hinzufügen, das im vorherigen Abschnitt erstellt wurde. Der Fokus liegt hier auf dem Schutz der API, nicht auf der Erstellung.
Importieren Sie die erforderlichen Pakete: Das
Microsoft.Identity.Web
Paket ist ein Wrapper um MSAL.NET, mit dem wir die Authentifizierungslogik wie die Verarbeitung der Tokenüberprüfung problemlos verarbeiten können. Um sicherzustellen, dass unsere Endpunkte eine Autorisierung erfordern, verwenden wir das integrierteMicrosoft.AspNetCore.Authorization
Paket.Da wir die Berechtigungen für den Aufruf dieser API entweder mithilfe von delegierten Berechtigungen im Namen des Benutzers oder mithilfe von Anwendungsberechtigungen erteilt haben, bei denen der Aufruf durch den Client selbst und nicht im Namen des Benutzers erfolgt, ist es wichtig zu wissen, ob der Aufruf von der App in ihrem eigenen Namen erfolgt. Am einfachsten finden Sie, ob das Zugriffstoken den
idtyp
optionalen Anspruch enthält. Der Anspruchidtyp
ist der einfachste Weg, wie die API feststellen kann, ob ein Token ein App-Token oder ein App- und Benutzertoken ist. Es wird empfohlen, den optionalen Anspruchidtyp
zu aktivieren.Wenn der Anspruch
idtyp
nicht aktiviert ist, können Sie die Ansprücheroles
undscp
verwenden, um zu bestimmen, ob es sich bei dem Zugriffstoken um ein App-Token oder um ein App- und Benutzertoken handelt. Ein von der Microsoft Entra-ID ausgestelltes Zugriffstoken verfügt über mindestens einen der beiden Ansprüche. Für Benutzende ausgestellte Zugriffstoken verfügen über den Anspruchscp
. Für eine Anwendung ausgestellte Zugriffstoken verfügen über den Anspruchroles
. Zugriffstoken, die beide Ansprüche enthalten, werden nur für Benutzer*innen ausgestellt, wobei der Anspruchscp
die delegierten Berechtigungen festlegt, während der Anspruchroles
die Rolle des Benutzers oder der Benutzerin festlegt. Zugriffstoken, die keinen der beiden Ansprüche enthalten, sind nicht zu berücksichtigen.private bool IsAppMakingRequest() { if (HttpContext.User.Claims.Any(c => c.Type == "idtyp")) { return HttpContext.User.Claims.Any(c => c.Type == "idtyp" && c.Value == "app"); } else { return HttpContext.User.Claims.Any(c => c.Type == "roles") && !HttpContext.User.Claims.Any(c => c.Type == "scp"); } }
Fügen Sie eine Hilfsfunktion hinzu, die feststellt, ob die gestellte Anforderung genügend Berechtigungen enthält, um die beabsichtigte Aktion auszuführen. Überprüfen Sie, ob die App die Anforderung im eigenen Namen stellt oder ob die App den Aufruf im Namen eines Benutzers oder einer Benutzerin tätigt, der*die Besitzer*in der betreffenden Ressource ist, indem wir die Benutzer-ID überprüfen.
private bool RequestCanAccessToDo(Guid userId) { return IsAppMakingRequest() || (userId == GetUserId()); } private Guid GetUserId() { Guid userId; if (!Guid.TryParse(HttpContext.User.GetObjectId(), out userId)) { throw new Exception("User ID is not valid."); } return userId; }
Fügen Sie die Berechtigungsdefinitionen ein, um Routen zu schützen. Schützen Sie Ihre API, indem Sie das Attribut
[Authorize]
zur Controllerklasse hinzufügen. Dadurch wird sichergestellt, dass die Controlleraktionen nur aufgerufen werden können, wenn die API mit einer autorisierten Identität aufgerufen wird. Die Berechtigungsdefinitionen legen fest, welche Arten von Berechtigungen zur Durchführung dieser Aktionen erforderlich sind.[Authorize] [Route("api/[controller]")] [ApiController] public class ToDoListController: ControllerBase{...}
Fügen Sie Berechtigungen zu den GET- und POST-Endpunkten hinzu. Dazu verwenden Sie die Methode RequiredScopeOrAppPermission, die Teil des Namespace Microsoft.Identity.Web.Resource ist. Anschließend übergeben Sie Bereiche und Berechtigungen über die Attribute RequiredScopesConfigurationKey und RequiredAppPermissionsConfigurationKey an diese Methode.
[HttpGet] [RequiredScopeOrAppPermission( RequiredScopesConfigurationKey = "AzureAD:Scopes:Read", RequiredAppPermissionsConfigurationKey = "AzureAD:AppPermissions:Read" )] public async Task<IActionResult> GetAsync() { var toDos = await _toDoContext.ToDos! .Where(td => RequestCanAccessToDo(td.Owner)) .ToListAsync(); return Ok(toDos); } [HttpPost] [RequiredScopeOrAppPermission( RequiredScopesConfigurationKey = "AzureAD:Scopes:Write", RequiredAppPermissionsConfigurationKey = "AzureAD:AppPermissions:Write" )] public async Task<IActionResult> PostAsync([FromBody] ToDo toDo) { // Only let applications with global to-do access set the user ID or to-do's var ownerIdOfTodo = IsAppMakingRequest() ? toDo.Owner : GetUserId(); var newToDo = new ToDo() { Owner = ownerIdOfTodo, Description = toDo.Description }; await _toDoContext.ToDos!.AddAsync(newToDo); await _toDoContext.SaveChangesAsync(); return Created($"/todo/{newToDo!.Id}", newToDo); }
Konfigurieren der API-Middleware für die Verwendung des Controllers
Als Nächstes konfigurieren wir die Anwendung so, dass controller für die Verarbeitung von HTTP-Anforderungen erkannt und verwendet werden. Öffnen Sie die program.cs
Datei, und fügen Sie den folgenden Code hinzu, um die Controllerdienste im Container zum Einfügen von Abhängigkeiten zu registrieren.
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
Im vorherigen Codeausschnitt bereitet die AddControllers()
-Methode die Anwendung auf die Verwendung von Controllern vor, indem die erforderlichen Dienste registriert werden, während MapControllers()
die Controllerrouten zugeordnet werden, um eingehende HTTP-Anforderungen zu verarbeiten.
Ihre API ausführen
Führen Sie Ihre API aus, um sicherzustellen, dass sie ohne Fehler mit dem Befehl dotnet run
ausgeführt wird. Wenn Sie das HTTPS-Protokoll auch während der Testphase verwenden möchten, müssen Sie dem Entwicklungszertifikat von .NET vertrauen.
Starten Sie die Anwendung, indem Sie Folgendes im Terminal eingeben:
dotnet run
Eine Ausgabe ähnlich der folgenden sollte im Terminal angezeigt werden. Dadurch wird bestätigt, dass die Anwendung unter
http://localhost:{port}
ausgeführt wird und auf Anforderungen lauscht.Building... info: Microsoft.Hosting.Lifetime[0] Now listening on: http://localhost:{port} info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. ...
Die Webseite http://localhost:{host}
zeigt eine Ausgabe ähnlich der folgenden Abbildung an. Dies liegt daran, dass die API ohne Authentifizierung aufgerufen wird. Informationen zum Zugreifen auf eine geschützte Web-API finden Sie in den nächsten Schritten , um einen autorisierten Aufruf auszuführen.
Ein vollständiges Beispiel für diesen API-Code finden Sie in der Beispieldatei.