Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Platí pro:
Tenanti pracovních sil
Externí tenanti (další informace)
Tato série kurzů ukazuje, jak chránit webové rozhraní API ASP.NET Core pomocí platformy Microsoft Identity Platform, aby byl omezen přístup jenom autorizovaným uživatelům a klientským aplikacím. Webové rozhraní API, které vytvoříte, používá delegovaná oprávnění (obory) i oprávnění aplikace (role aplikací).
V tomto kurzu se naučíte:
- Vytvoření webového rozhraní API ASP.NET Core
- Nakonfigurujte webové rozhraní API tak, aby používalo podrobnosti registrace aplikace Microsoft Entra.
- Ochrana koncových bodů webového rozhraní API
- Spuštěním webového rozhraní API se ujistěte, že naslouchá požadavkům HTTP.
Požadavky
- Pokud jste to ještě neudělali, proveďte kroky v rychlém startu: Volání webového rozhraní API chráněného platformou Microsoft Identity Platform. Nemusíte klonovat a spouštět ukázku kódu, ale ujistěte se, že máte následující:
- Podrobnosti o registraci aplikace webového rozhraní API z Centra pro správu Microsoft Entra, včetně ID klienta a ID tenanta.
- ToDoList.Read a ToDoList.ReadWrite jako delegovaná oprávnění (obory) vystavená webovým rozhraním API
- ToDoList.Read.All a ToDoList.ReadWrite.All jako oprávnění aplikace (role aplikací) vystavená webovým rozhraním API
- .NET 8.0 SDK nebo novější.
- Visual Studio Code nebo jiného editoru kódu.
Vytvoření nového projektu webového rozhraní API ASP.NET Core
Pokud chcete vytvořit minimální projekt webového rozhraní API ASP.NET Core, postupujte takto:
Otevřete terminál v editoru Visual Studio Code nebo jiném editoru kódu a přejděte do adresáře, kam chcete projekt vytvořit.
Na .NET CLI nebo jiném nástroji příkazového řádku spusťte následující příkazy.
dotnet new web -o TodoListApi cd TodoListApiVyberte Ano, když se zobrazí dialogové okno s dotazem, jestli chcete autorům důvěřovat.
Vyberte Ano Když se zobrazí dialogové okno s dotazem, jestli chcete do projektu přidat požadované prostředky.
Instalace požadovaných balíčků
Pokud chcete sestavit, chránit a otestovat webové rozhraní API ASP.NET Core, musíte nainstalovat následující balíčky:
-
Microsoft.EntityFrameworkCore.InMemory– Balíček, který umožňuje používat Entity Framework Core s databází v paměti. Je užitečná pro účely testování, ale není určená pro produkční použití. -
Microsoft.Identity.Web– sada ASP.NET základních knihoven, které zjednodušují přidávání podpory ověřování a autorizace do webových aplikací a webových rozhraní API, které se integrují s platformou Microsoft Identity Platform.
K instalaci balíčku použijte:
dotnet add package Microsoft.EntityFrameworkCore.InMemory
dotnet add package Microsoft.Identity.Web
Konfigurace podrobností registrace aplikace
Otevřete soubor appsettings.json ve složce aplikace a přidejte podrobnosti o registraci aplikace, které jste si poznamenali po registraci webového rozhraní API.
{
"AzureAd": {
"Instance": "Enter_the_Authority_URL_Here",
"TenantId": "Enter_the_Tenant_Id_Here",
"ClientId": "Enter_the_Application_Id_Here"
},
"Logging": {...},
"AllowedHosts": "*"
}
Nahraďte následující zástupné symboly, jak je znázorněno:
- Nahraďte
Enter_the_Application_Id_HereID vaší aplikace (klienta). - Nahraďte
Enter_the_Tenant_Id_Hereidentifikátorem tenanta. - Nahraďte
Enter_the_Authority_URL_Hereadresou URL autority, jak je to vysvětleno v další části.
Adresa URL autority pro vaši aplikaci
Adresa URL autority určuje adresář, ze kterého může microsoft Authentication Library (MSAL) požadovat tokeny. Sestavíte to jak pro pracovní sílu, tak pro externí nájemce odlišně, jak je znázorněno:
//Instance for workforce tenant
Instance: "https://login.microsoftonline.com/"
Použití vlastní domény URL (volitelné)
V tenantech pro pracovníky nejsou podporovány vlastní domény URL.
Přidání oprávnění
Všechna rozhraní API musí publikovat minimálně jeden obor, označovaný také jako delegovaná oprávnění, aby klientské aplikace získaly přístupový token pro uživatele. Rozhraní API by také měla publikovat alespoň jednu roli aplikace, označovanou také jako oprávnění aplikace, aby klientské aplikace získaly přístupový token samostatně, tzn. když se nepřihlašují jako uživatel.
Tato oprávnění zadáme do souboru appsettings.json. V tomto kurzu jste zaregistrovali následující delegovaná oprávnění a oprávnění aplikace:
- Delegovaná oprávnění:ToDoList.Read a ToDoList.ReadWrite.
- Oprávnění aplikací:ToDoList.Read.All a ToDoList.ReadWrite.All.
Když uživatel nebo klientská aplikace volá webové rozhraní API, mají oprávnění k přístupu k chráněnému koncovému bodu pouze klienti s těmito obory nebo oprávněními.
{
"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": "*"
}
Implementace ověřování a autorizace v rozhraní API
Pokud chcete nakonfigurovat ověřování a autorizaci, otevřete soubor program.cs a nahraďte jeho obsah následujícími fragmenty kódu:
Přidání schématu ověřování
V tomto rozhraní API používáme schéma nosných tokenů JSON (JWT) jako výchozí mechanismus ověřování. Pomocí metody AddAuthentication zaregistrujte schéma nosiče 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);
Vytvoření modelu aplikace
V kořenové složce projektu vytvořte složku s názvem Modely. Přejděte do složky Models a vytvořte soubor s názvem ToDo.cs a přidejte následující kód.
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;
}
Předchozí kód vytvoří model s názvem ToDo. Tento model představuje data, která aplikace spravuje.
Přidání kontextu databáze
Dále definujeme třídu kontextu databáze, která koordinuje funkce Entity Framework pro datový model. Tato třída dědí z Třídy Microsoft.EntityFrameworkCore.DbContext , která spravuje interakce mezi aplikací a databází. Pokud chcete přidat kontext databáze, postupujte takto:
Vytvořte složku s názvem DbContext v kořenové složce projektu.
Přejděte do složky DbContext a vytvořte soubor s názvem
ToDoContext.csa přidejte následující kód: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; } }Otevřete soubor Program.cs v kořenové složce projektu a aktualizujte ho následujícím kódem:
// 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"));
V předchozím fragmentu kódu zaregistrujeme kontext databáze jako službu s vymezeným oborem ve zprostředkovateli aplikační služby ASP.NET Core (označovaný také jako kontejner injektáže závislostí). Třídu ToDoContext také nakonfigurujete tak, aby používala databázi uloženou v paměti pro rozhraní API seznamu úkolů.
Nastavení kontroleru
Kontrolery obvykle implementují akce vytvoření, čtení, aktualizace a odstranění (CRUD) pro správu prostředků. Vzhledem k tomu, že se tento kurz zaměřuje spíše na ochranu koncových bodů rozhraní API, implementujeme v kontroleru pouze dvě položky akcí. Akce Číst vše pro načtení všech To-Do položek a akce Vytvořit pro přidání nové To-Do položky. Pokud chcete do projektu přidat kontroler, postupujte takto:
Přejděte do kořenové složky projektu a vytvořte složku s názvem Kontrolery.
Vytvořte soubor s názvem
ToDoListController.csve složce Controllers a přidejte následující kód kotelní desky:
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(){...}
}
Přidání kódu do kontroleru
Tato část vysvětluje, jak přidat kód do vygenerovaného kontroleru v předchozí části. Tady je fokus na ochranu rozhraní API, nikoli na jeho sestavení.
Naimportujte potřebné balíčky: Balíček
Microsoft.Identity.Webje obálka kolem MSAL.NET, která nám pomáhá snadno zpracovat logiku ověřování, jako je zpracování ověřování tokenů. Abychom zajistili, že naše koncové body vyžadují autorizaci, použijeme připravenýMicrosoft.AspNetCore.Authorizationbalíček.Vzhledem k tomu, že jsme udělili oprávnění k volání tohoto rozhraní API buď pomocí delegovaných oprávnění jménem uživatele nebo aplikace, kde klient volá jako sám sebe, a ne jménem uživatele, je důležité vědět, jestli volání provádí aplikace vlastním jménem. Nejjednodušším způsobem, jak to udělat, je zjistit, zda přístupový token obsahuje volitelný
idtypnárok. Totoidtyptvrzení je nejjednodušším způsobem pro rozhraní API, jak určit, zda je token tokenem aplikace nebo tokenem aplikace/uživatele. Doporučujeme povolit volitelný nárokidtyp.Pokud deklarace
idtypnení povolena, můžete pomocí deklaracírolesascpurčit, zda je přístupový token aplikace nebo token aplikace a uživatele. Přístupový token od Microsoft Entra ID má alespoň jeden ze dvou nároků. Přístupové tokeny vydané uživateli obsahují nárokscp. Přístupové tokeny vydané pro aplikaci mají nárokroles. Přístupové tokeny, které obsahují obě deklarace identity, se vydávají jenom uživatelům, kdescpdeklarace identity určuje delegovaná oprávnění, zatímcorolesdeklarace identity určuje roli uživatele. Přístupové tokeny, které nemají žádné z uvedených vlastností, by neměly být uznány.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"); } }Přidejte pomocnou funkci, která určuje, jestli provedený požadavek obsahuje dostatečná oprávnění k provedení zamýšlené akce. Zkontrolujte, jestli aplikace provádí žádost vlastním jménem nebo jestli aplikace volá jménem uživatele, který daný prostředek vlastní, tím, že ověří ID uživatele.
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; }Připojte definice oprávnění k ochraně tras. Chraňte své rozhraní API přidáním
[Authorize]atributu do třídy kontroleru. Tím se zajistí, že akce kontroleru lze volat pouze v případě, že se rozhraní API volá s autorizovanou identitou. Definice oprávnění definují, jaké druhy oprávnění jsou potřeba k provedení těchto akcí.[Authorize] [Route("api/[controller]")] [ApiController] public class ToDoListController: ControllerBase{...}Přidejte oprávnění ke koncovým bodům GET a POST. Použijte metodu RequiredScopeOrAppPermission , která je součástí oboru názvů Microsoft.Identity.Web.Resource . Pak předáte obory a oprávnění této metodě prostřednictvím RequiredScopesConfigurationKey a RequiredAppPermissionsConfigurationKey atributy.
[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); }
Konfigurace middlewaru rozhraní API pro použití kontroleru
Dále nakonfigurujeme aplikaci tak, aby rozpoznala a používala kontrolery pro zpracování požadavků HTTP. Otevřete soubor program.cs a přidejte následující kód pro registraci služeb kontroleru v kontejneru pro injektáž závislostí.
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
V předchozím fragmentu kódu metoda AddControllers() připraví aplikaci na používání kontrolerů registrací potřebných služeb, zatímco MapControllers() mapuje trasy kontrolerů pro zpracování příchozích HTTP požadavků.
Spuštění rozhraní API
Spusťte příkaz dotnet runk ověření, že vaše rozhraní API běží bez chyb. Pokud máte v úmyslu používat protokol HTTPS i během testování, musíte důvěřovat vývojovému certifikátu .NET.
Spusťte aplikaci zadáním následujícího příkazu v terminálu:
dotnet runV terminálu by se měl zobrazit výstup podobný následujícímu, který potvrzuje, že aplikace běží na
http://localhost:{port}a naslouchá požadavkům.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. ...
Webová stránka http://localhost:{host} zobrazí výstup podobný následujícímu obrázku. Důvodem je to, že se rozhraní API volá bez ověřování. Pokud chcete provést autorizované volání, přečtěte si pokyny Další kroky k přístupu k chráněnému webovému rozhraní API.
Úplný příklad tohoto kódu rozhraní API najdete v ukázkovém souboru.