Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
pl-PL: Dotyczy: Najemcy Workforce
Zewnętrzni najemcy (więcej informacji)
W tej serii samouczków pokazano, jak chronić internetowy interfejs API ASP.NET Core za pomocą platformy tożsamości firmy Microsoft, aby ograniczyć dostęp tylko do autoryzowanych użytkowników i aplikacji klienckich. Kompilowany internetowy interfejs API używa uprawnień delegowanych (zakresów) i uprawnień aplikacji (ról aplikacji).
W tym samouczku nauczysz się następujących rzeczy:
- Tworzenie internetowego interfejsu API platformy ASP.NET Core
- Skonfiguruj internetowy interfejs API, aby używać szczegółów rejestracji aplikacji Microsoft Entra
- Chroń punkty końcowe interfejsu API
- Uruchom internetowy interfejs API, aby upewnić się, że nasłuchuje żądań HTTP
Warunki wstępne
- Jeśli jeszcze tego nie zrobiono, wykonaj kroki opisane w przewodniku Szybki start: wywoływanie internetowego interfejsu API chronionego przez platformę tożsamości firmy Microsoft. Nie musisz klonować i uruchamiać przykładowego kodu, ale upewnij się, że masz następujące elementy:
- Szczegóły rejestracji aplikacji API sieciowego z centrum administracyjnego Entra firmy Microsoft, w tym identyfikator klienta i identyfikator dzierżawy.
- ToDoList.Read i ToDoList.ReadWrite jako delegowane uprawnienia (zakresy) udostępniane przez internetowy interfejs API
- ToDoList.Read.All i ToDoList.ReadWrite.All jako uprawnienia aplikacji (role aplikacji) uwidocznione przez internetowy interfejs API
- zestaw SDK platformy .NET 8.0 lub nowszy.
- Visual Studio Code lub innego edytora kodu.
Tworzenie nowego projektu internetowego interfejsu API platformy ASP.NET Core
Aby utworzyć minimalny projekt internetowego interfejsu API platformy ASP.NET Core, wykonaj następujące kroki:
Otwórz terminal w programie Visual Studio Code lub innym edytorze kodu i przejdź do katalogu, w którym chcesz utworzyć projekt.
Uruchom następujące polecenia w interfejsie wiersza polecenia platformy .NET lub innym narzędziu wiersza polecenia.
dotnet new web -o TodoListApi cd TodoListApi
Wybierz pozycję Tak, gdy zostanie wyświetlone okno dialogowe z pytaniem, czy chcesz ufać autorom.
Wybierz pozycję Tak Gdy w oknie dialogowym zostanie wyświetlone pytanie, czy chcesz dodać wymagane zasoby do projektu.
Instalowanie wymaganych pakietów
Aby skompilować, chronić i przetestować internetowy interfejs API platformy ASP.NET Core, należy zainstalować następujące pakiety:
-
Microsoft.EntityFrameworkCore.InMemory
— Pakiet, który umożliwia korzystanie z programu Entity Framework Core z bazą danych w pamięci. Jest to przydatne do celów testowych, ale nie jest przeznaczone do użytku produkcyjnego. -
Microsoft.Identity.Web
— zestaw bibliotek ASP.NET Core, które upraszczają dodawanie obsługi uwierzytelniania i autoryzacji do aplikacji internetowych i internetowych interfejsów API integrujących się z platformą tożsamości firmy Microsoft.
Aby zainstalować pakiet, użyj:
dotnet add package Microsoft.EntityFrameworkCore.InMemory
dotnet add package Microsoft.Identity.Web
Konfigurowanie szczegółów rejestracji aplikacji
Otwórz plik appsettings.json w folderze aplikacji i dodaj szczegóły rejestracji aplikacji, które zapisałeś po zarejestrowaniu interfejsu API sieci.
{
"AzureAd": {
"Instance": "Enter_the_Authority_URL_Here",
"TenantId": "Enter_the_Tenant_Id_Here",
"ClientId": "Enter_the_Application_Id_Here"
},
"Logging": {...},
"AllowedHosts": "*"
}
Zastąp następujące elementy zastępcze zgodnie z poniższymi instrukcjami.
- Zastąp
Enter_the_Application_Id_Here
identyfikatorem aplikacji (klienta). - Zastąp
Enter_the_Tenant_Id_Here
swoim identyfikatorem katalogu (dzierżawcy). - Zastąp
Enter_the_Authority_URL_Here
adresem URL autorytetu, jak wyjaśniono w następnej sekcji.
Adres URL autoryzacji dla aplikacji
Adres URL urzędu określa katalog, z którego biblioteka Microsoft Authentication Library (MSAL) może żądać tokenów. Budowanie odbywa się inaczej w przypadku zarówno siły roboczej, jak i najemców zewnętrznych, jak pokazano.
//Instance for workforce tenant
Instance: "https://login.microsoftonline.com/"
Użyj niestandardowej domeny adresu URL (opcjonalnie)
Niestandardowe domeny adresów URL nie są obsługiwane w dzierżawach dla zespołów pracowniczych.
Dodawanie uprawnień
Wszystkie interfejsy API muszą opublikować co najmniej jeden zakres, nazywany również uprawnieniem delegowanym, aby aplikacje klienckie pomyślnie uzyskały token dostępu dla użytkownika. Interfejsy API powinny również publikować co najmniej jedną rolę aplikacji, nazywaną również uprawnieniami aplikacji, aby aplikacje klienckie mogły uzyskać token dostępu w imieniu siebie samych, czyli wtedy, gdy nie logują się użytkownikiem.
Określamy te uprawnienia w pliku appsettings.json. W tym samouczku zarejestrowałeś następujące uprawnienia delegowane i aplikacyjne:
- Delegowane uprawnienia:ToDoList.Read i ToDoList.ReadWrite.
- Uprawnienia aplikacji:ToDoList.Read.All i ToDoList.ReadWrite.All.
Gdy użytkownik lub aplikacja kliencka wywołuje internetowy interfejs API, tylko klienci z tymi zakresami lub uprawnieniami uzyskują uprawnienia dostępu do chronionego punktu końcowego.
{
"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": "*"
}
Implementowanie uwierzytelniania i autoryzacji w interfejsie API
Aby skonfigurować uwierzytelnianie i autoryzację, otwórz plik program.cs
i zastąp jego zawartość następującymi fragmentami kodu:
Dodawanie schematu uwierzytelniania
W tym interfejsie API używamy schematu elementu nośnego JSON Web Token (JWT) jako domyślnego mechanizmu uwierzytelniania. Użyj metody AddAuthentication
, aby zarejestrować schemat uwierzytelniania JWT.
// 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);
Tworzenie modelu aplikacji
W folderze głównym projektu utwórz folder o nazwie Models. Przejdź do folderu Models i utwórz plik o nazwie ToDo.cs
, a następnie dodaj następujący kod.
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;
}
Powyższy kod tworzy model o nazwie ToDo. Ten model reprezentuje dane zarządzane przez aplikację.
Dodawanie kontekstu bazy danych
Następnie zdefiniujemy klasę kontekstu bazy danych, która koordynuje funkcjonalność programu Entity Framework dla modelu danych. Ta klasa dziedziczy z klasy Microsoft.EntityFrameworkCore.DbContext , która zarządza interakcjami między aplikacją a bazą danych. Aby dodać kontekst bazy danych, wykonaj następujące kroki:
Utwórz folder o nazwie DbContext w folderze głównym projektu.
Przejdź do folderu DbContext i utwórz plik o nazwie
ToDoContext.cs
, a następnie dodaj następujący kod: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; } }
Otwórz plik Program.cs w folderze głównym projektu i zaktualizuj go przy użyciu następującego kodu:
// 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"));
W poprzednim fragmencie kodu rejestrujemy kontekst bazy danych jako usługę o określonym zakresie w dostawcy usługi aplikacji ASP.NET Core (nazywanego również kontenerem wstrzykiwania zależności). Należy również skonfigurować klasę ToDoContext
tak, aby korzystała z bazy danych w pamięci dla interfejsu API listy zadań do wykonania.
Konfigurowanie kontrolera
Kontrolery zazwyczaj implementują akcje Tworzenia, odczytu, aktualizacji i usuwania (CRUD) w celu zarządzania zasobami. Ponieważ ten samouczek koncentruje się bardziej na ochronie punktów końcowych interfejsu API, implementujemy tylko dwa elementy akcji w kontrolerze. Akcja Odczytaj wszystkie, aby pobrać wszystkie elementy To-Do i akcję Utwórz, aby dodać nowy element To-Do. Wykonaj następujące kroki, aby dodać kontroler do projektu:
Przejdź do folderu głównego projektu i utwórz folder o nazwie Controllers.
Utwórz plik o nazwie
ToDoListController.cs
w folderze Controllers i dodaj następujący kod płyty kotłowej:
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(){...}
}
Dodawanie kodu do kontrolera
W tej sekcji wyjaśniono, jak dodać kod do kontrolera utworzonego w poprzedniej sekcji. Tutaj koncentrujemy się na ochronie interfejsu API, a nie na tworzeniu go.
Zaimportuj niezbędne pakiety: Pakiet
Microsoft.Identity.Web
jest opakowaniem MSAL.NET, które ułatwia obsługę logiki uwierzytelniania, takiej jak obsługa walidacji tokenu. Aby upewnić się, że nasze punkty końcowe wymagają autoryzacji, użyjemy wbudowanegoMicrosoft.AspNetCore.Authorization
pakietu.Ponieważ przyznaliśmy uprawnienia do wywoływania tego interfejsu API, używając uprawnień delegowanych w imieniu użytkownika lub uprawnień aplikacji, gdzie klient działa we własnym imieniu, a nie w imieniu użytkownika, ważne jest, aby wiedzieć, czy wywołanie jest wykonywane przez aplikację we własnym imieniu. Najprostszym sposobem jest znalezienie, czy token dostępu zawiera
idtyp
opcjonalne oświadczenie. Toidtyp
oświadczenie jest najprostszym sposobem dla interfejsu API, aby określić, czy token jest tokenem aplikacji, czy tokenem aplikacji i użytkownika. Zalecamy włączenie opcjonalnegoidtyp
atrybutu.idtyp
Jeśli oświadczenie nie jest włączone, możesz użyćroles
iscp
oświadczeń, aby określić, czy token dostępu jest tokenem aplikacji, czy tokenem aplikacji + użytkownika. Token dostępu wystawiony przez Microsoft Entra ID ma co najmniej jedno z dwóch roszczeń. Tokeny dostępu wystawione dla użytkownika mająscp
atrybut. Tokeny dostępu wydane dla aplikacji zawierają atrybutroles
. Tokeny dostępu zawierające oba oświadczenia są wystawiane tylko dla użytkowników, gdziescp
oświadczenie wyznacza delegowane uprawnienia, podczas gdyroles
oświadczenie wyznacza rolę użytkownika. Tokeny dostępu, które nie mają żadnego z nich, nie mają być honorowane.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"); } }
Dodaj funkcję pomocnika, która określa, czy wykonywane żądanie zawiera wystarczające uprawnienia do wykonania zamierzonej akcji. Sprawdź, czy jest to aplikacja wysyłająca żądanie we własnym imieniu, czy też aplikacja wykonuje wywołanie w imieniu użytkownika, który jest właścicielem danego zasobu, sprawdzając identyfikator użytkownika.
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; }
Wprowadź definicje uprawnień, aby chronić ścieżki. Chroń interfejs API, dodając
[Authorize]
atrybut do klasy kontrolera. Dzięki temu akcje kontrolera mogą być wywoływane tylko wtedy, gdy interfejs API jest wywoływany z autoryzowaną tożsamością. Definicje uprawnień określają, jakie rodzaje uprawnień są potrzebne do wykonania tych akcji.[Authorize] [Route("api/[controller]")] [ApiController] public class ToDoListController: ControllerBase{...}
Dodaj uprawnienia do punktów końcowych GET i POST. W tym celu należy użyć metody RequiredScopeOrAppPermission , która jest częścią przestrzeni nazw Microsoft.Identity.Web.Resource . Następnie przekazujesz zakresy i uprawnienia do tej metody za pomocą atrybutów RequiredScopesConfigurationKey i 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); }
Konfiguracja middleware API do użycia kontrolera
Następnie skonfigurujemy aplikację do rozpoznawania i używania kontrolerów do obsługi żądań HTTP.
program.cs
Otwórz plik i dodaj następujący kod, aby zarejestrować usługi kontrolera w kontenerze iniekcji zależności.
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
W poprzednim fragmencie AddControllers()
kodu metoda przygotowuje aplikację do korzystania z kontrolerów, rejestrując niezbędne usługi, mapując MapControllers()
trasy kontrolera na obsługę przychodzących żądań HTTP.
Uruchamianie interfejsu API
Uruchom interfejs API, aby upewnić się, że działa bez żadnych błędów przy użyciu polecenia dotnet run
. Jeśli zamierzasz używać protokołu HTTPS nawet podczas testowania, musisz zaufać certyfikatowi programistycznemu .NET.
Uruchom aplikację, wpisując następujące polecenie w terminalu:
dotnet run
Powinien zostać wyświetlony wynik podobny do poniższego w terminalu, co potwierdza, że aplikacja jest uruchomiona na
http://localhost:{port}
, i nasłuchuje żądań.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. ...
Strona internetowa http://localhost:{host}
wyświetla dane wyjściowe podobne do poniższego obrazu. Dzieje się tak, ponieważ interfejs API jest wywoływany bez uwierzytelniania. Aby wykonać autoryzowane wywołanie, zapoznaj się z Następne kroki, aby uzyskać wskazówki dotyczące uzyskiwania dostępu do chronionego sieciowego interfejsu API.
Pełny przykład tego kodu interfejsu API można znaleźć w pliku przykładów .