Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of mappen te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen om mappen te wijzigen.
Van toepassing op:
Werknemerstenants
Externe tenants (meer informatie)
Deze reeks zelfstudies laat zien hoe u een ASP.NET Core-web-API beveiligt met het Microsoft Identity Platform om de toegang tot alleen geautoriseerde gebruikers en client-apps te beperken. De web-API die u bouwt, maakt gebruik van zowel gedelegeerde machtigingen (bereiken) als toepassingsmachtigingen (app-rollen).
In deze handleiding leert u:
- Een ASP.NET Core-web-API bouwen
- De web-API configureren voor het gebruik van de microsoft Entra-app-registratiegegevens
- Uw web-API-eindpunten beveiligen
- Voer de web-API uit om ervoor te zorgen dat deze luistert naar HTTP-aanvragen
Voorwaarden
- Als u dat nog niet hebt gedaan, voert u de stappen in quickstart uit: Een web-API aanroepen die wordt beveiligd door het Microsoft Identity Platform. U hoeft het codevoorbeeld niet te klonen en uit te voeren, maar zorg ervoor dat u het volgende hebt:
- De app-registratiegegevens van de web-API vanuit het Microsoft Entra-beheercentrum, inclusief de client-id en tenant-id.
- ToDoList.Read en ToDoList.ReadWrite als gedelegeerde machtigingen (bereiken) die worden weergegeven door de web-API
- ToDoList.Read.All en ToDoList.ReadWrite.All als de toepassingsmachtigingen (app-rollen) die worden weergegeven door de web-API
- .NET 8.0 SDK of hoger.
- Visual Studio Code of een andere code-editor.
Een nieuw ASP.NET Core-web-API-project maken
Voer de volgende stappen uit om een minimaal ASP.NET Core-web-API-project te maken:
Open uw terminal in Visual Studio Code of een andere code-editor en navigeer naar de map waar u uw project wilt maken.
Voer de volgende opdrachten uit op de .NET CLI of een ander opdrachtregelprogramma.
dotnet new web -o TodoListApi cd TodoListApiSelecteer Ja wanneer u in een dialoogvenster wordt gevraagd of u de auteurs wilt vertrouwen.
Selecteer Ja Wanneer u in een dialoogvenster wordt gevraagd of u de vereiste assets wilt toevoegen aan het project.
Vereiste pakketten installeren
Als u de ASP.NET Core-web-API wilt bouwen, beveiligen en testen, moet u de volgende pakketten installeren:
-
Microsoft.EntityFrameworkCore.InMemory- Een pakket waarmee u de Entity Framework Core kunt gebruiken met een in-memory database. Het is handig voor testdoeleinden, maar is niet ontworpen voor productiegebruik. -
Microsoft.Identity.Web- een set ASP.NET Core-bibliotheken die het toevoegen van verificatie- en autorisatieondersteuning vereenvoudigen voor web-apps en web-API's die zijn geïntegreerd met het Microsoft Identity Platform.
Als u het pakket wilt installeren, gebruikt u:
dotnet add package Microsoft.EntityFrameworkCore.InMemory
dotnet add package Microsoft.Identity.Web
Details van app-registratie configureren
Open het appsettings.json-bestand in de app-map en voeg de app-registratiegegevens toe die u hebt vastgelegd nadat u de web-API hebt geregistreerd.
{
"AzureAd": {
"Instance": "Enter_the_Authority_URL_Here",
"TenantId": "Enter_the_Tenant_Id_Here",
"ClientId": "Enter_the_Application_Id_Here"
},
"Logging": {...},
"AllowedHosts": "*"
}
Vervang de volgende tijdelijke aanduidingen zoals weergegeven:
- Vervang
Enter_the_Application_Id_Heredoor de id van uw toepassing (client). - Vervang
Enter_the_Tenant_Id_Heredoor uw directory-ID (tenant-ID). - Vervang
Enter_the_Authority_URL_Heredoor de URL van uw instantie, zoals wordt uitgelegd in de volgende sectie.
URL van de autoriteit voor uw app
De instantie-URL specificeert de directory waarvan Microsoft Authentication Library (MSAL) tokens kan aanvragen. U bouwt het anders qua personeelsbestand en externe huurders, zoals weergegeven.
//Instance for workforce tenant
Instance: "https://login.microsoftonline.com/"
Aangepast URL-domein gebruiken (optioneel)
Aangepaste URL-domeinen worden niet ondersteund in werkplekhuren.
Machtigingen toevoegen
Alle API's moeten minimaal één scope, ook wel gedelegeerde machtiging genoemd, publiceren zodat de client-apps met succes een toegangstoken voor een gebruiker kunnen verkrijgen. API's moeten ook minimaal één app-rol, ook wel toepassingsmachtigingen genoemd, publiceren, zodat de client-apps zelf een toegangstoken kunnen verkrijgen, dat wil gezegd wanneer ze zich niet aanmelden bij een gebruiker.
We geven deze machtigingen op in het appsettings.json-bestand. In deze zelfstudie hebt u de volgende gedelegeerde machtigingen en toepassingsmachtigingen geregistreerd:
- Gedelegeerde machtigingen:ToDoList.Read en ToDoList.ReadWrite.
- Toepassingsmachtigingen:ToDoList.Read.All en ToDoList.ReadWrite.All.
Wanneer een gebruiker of clienttoepassing de web-API aanroept, worden alleen clients met deze bereiken of machtigingen geautoriseerd voor toegang tot het beveiligde eindpunt.
{
"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": "*"
}
Verificatie en autorisatie implementeren in de API
Als u verificatie en autorisatie wilt configureren, opent u het program.cs-bestand en vervangt u de inhoud van de volgende codefragmenten:
Een verificatieschema toevoegen
In deze API gebruiken we het Bearer-schema JSON Web Token (JWT) als het standaardverificatiemechanisme. Gebruik de methode AddAuthentication om het JWT bearer-schema te registreren.
// 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);
Het model van uw app maken
Maak in de hoofdmap van het project een map met de naam Modellen. Navigeer naar de map Modellen en maak een bestand met de naam ToDo.cs en voeg vervolgens de volgende code toe.
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;
}
Met de voorgaande code maakt u een model met de naam ToDo. Dit model vertegenwoordigt gegevens die door de app worden beheerd.
Een databasecontext toevoegen
Vervolgens definiëren we een databasecontextklasse, die de Entity Framework-functionaliteit coördineert voor een gegevensmodel. Deze klasse neemt over van de klasse Microsoft.EntityFrameworkCore.DbContext waarmee interacties tussen de toepassing en de database worden beheerd. Voer de volgende stappen uit om de databasecontext toe te voegen:
Maak een map met de naam DbContext in de hoofdmap van uw project.
Navigeer naar de map DbContext en maak een bestand met de naam
ToDoContext.csen voeg de volgende code toe: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; } }Open het Program.cs-bestand in de hoofdmap van uw project en werk het bij met de volgende 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"));
In het voorgaande codefragment registreren we DB Context als een scoped service in de ASP.NET Core-toepassingsserviceprovider (ook wel bekend als de container voor afhankelijkheidsinjectie). U configureert ook de ToDoContext klasse voor het gebruik van een in-memory database voor de Takenlijst-API.
Een controller instellen
Controllers implementeren doorgaans CRUD-acties (Create, Read, Update en Delete) om resources te beheren. Omdat deze zelfstudie zich meer richt op het beveiligen van de API-eindpunten, implementeren we slechts twee actie-items in de controller. Een 'Alles lezen'-actie om alle To-Do items op te halen en een 'Maken'-actie om een nieuw To-Do item toe te voegen. Volg deze stappen om een controller toe te voegen aan uw project:
Navigeer naar de hoofdmap van uw project en maak een map met de naam Controllers.
Maak een bestand met de naam
ToDoListController.csin de map Controllers en voeg de volgende standaardplaatcode toe:
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(){...}
}
Code toevoegen aan de controller
In deze sectie wordt uitgelegd hoe u code toevoegt aan de controller die in de vorige sectie is geïnstalleerd. De focus hier ligt op het beveiligen van de API, niet op het bouwen ervan.
Importeer de benodigde pakketten: Het
Microsoft.Identity.Webpakket is een wrapper rond MSAL.NET waarmee we eenvoudig verificatielogica kunnen afhandelen, zoals het afhandelen van tokenvalidatie. Om ervoor te zorgen dat voor onze eindpunten autorisatie is vereist, gebruiken we het ingebouwdeMicrosoft.AspNetCore.Authorizationpakket.Omdat we machtigingen hebben verleend voor deze API die moet worden aangeroepen met gedelegeerde machtigingen namens de gebruiker of toepassingsmachtigingen waarbij de client zichzelf aanroept en niet namens de gebruiker, is het belangrijk om te weten of de aanroep door de app zelf wordt gedaan. De eenvoudigste manier om dit te doen, is om te bepalen of het toegangstoken de
idtypoptionele claim bevat. Dezeidtypclaim is de eenvoudigste manier voor de API om te bepalen of een token een app-token is of een app + gebruikerstoken. We raden aan om deidtypoptionele claim in te schakelen.Als de
idtypclaim niet is ingeschakeld, kunt u derolesenscpclaims gebruiken om te bepalen of het toegangstoken een app-token of een app + gebruikerstoken is. Een toegangstoken dat is uitgegeven door Microsoft Entra ID heeft ten minste één van de twee claims. Toegangstokens die zijn uitgegeven aan een gebruiker, hebben descpclaim. Toegangstokens die zijn uitgegeven aan een toepassing, hebben derolesclaim. Toegangstokens die beide claims bevatten, worden alleen verleend aan gebruikers, waarbij descpclaim de gedelegeerde machtigingen aanwijst, terwijl derolesclaim de rol van de gebruiker aanwijst. Toegangstokens die geen van beide attributen hebben, moeten niet worden gehonoreerd.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"); } }Voeg een helperfunctie toe die bepaalt of de aanvraag die wordt gedaan voldoende machtigingen bevat om de beoogde actie uit te voeren. Controleer of de app de aanvraag zelf indient of dat de app de aanroep doet namens een gebruiker die eigenaar is van de opgegeven resource door de gebruikers-id te valideren.
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; }Sluit uw machtigingsdefinities aan om routes te beveiligen. Beveilig uw API door het
[Authorize]kenmerk toe te voegen aan de controllerklasse. Dit zorgt ervoor dat de controlleracties alleen kunnen worden aangeroepen als de API wordt aangeroepen met een geautoriseerde identiteit. De machtigingsdefinities definiëren welke soorten machtigingen nodig zijn om deze acties uit te voeren.[Authorize] [Route("api/[controller]")] [ApiController] public class ToDoListController: ControllerBase{...}Voeg machtigingen toe aan de GET- en POST-eindpunten. Gebruik hiervoor de methode RequiredScopeOrAppPermission die deel uitmaakt van de naamruimte Microsoft.Identity.Web.Resource . Vervolgens geeft u bereiken en machtigingen door aan deze methode via de parameters RequiredScopesConfigurationKey en RequiredAppPermissionsConfigurationKey.
[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); }
De API-middleware configureren voor het gebruik van de controller
Vervolgens configureren we de toepassing voor het herkennen en gebruiken van controllers voor het verwerken van HTTP-aanvragen. Open het program.cs bestand en voeg de volgende code toe om de controllerservices te registreren in de container voor afhankelijkheidsinjectie.
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
In het voorgaande codefragment bereidt de AddControllers() methode de toepassing voor op het gebruik van controllers door de benodigde services te registreren terwijl MapControllers() de controllerroutes worden toegewezen om binnenkomende HTTP-aanvragen te verwerken.
Uw API uitvoeren
Voer uw API uit om ervoor te zorgen dat deze zonder fouten wordt uitgevoerd met behulp van de opdracht dotnet run. Als u van plan bent het HTTPS-protocol zelfs tijdens het testen te gebruiken, moet u het ontwikkelingscertificaat van .NET vertrouwen.
Start de toepassing door het volgende in de terminal te typen:
dotnet runEr zou een uitvoer moeten worden weergegeven in de terminal die lijkt op het onderstaande, waarmee wordt bevestigd dat de toepassing actief is op
http://localhost:{port}en luistert naar aanvragen.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. ...
Op de webpagina http://localhost:{host} wordt een uitvoer weergegeven die vergelijkbaar is met de volgende afbeelding. Dit komt doordat de API zonder verificatie wordt aangeroepen. Als u een geautoriseerde aanroep wilt maken, raadpleegt u Volgende stappen voor hulp bij het openen van een beveiligde web-API.
Zie het bestand voorbeeldenvoor een volledig voorbeeld van deze API-code.