Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Berlaku untuk: Penyewa tenaga kerja
Penyewa eksternal (pelajari lebih lanjut)
Seri tutorial ini menunjukkan cara melindungi API web ASP.NET Core dengan platform identitas Microsoft untuk membatasi aksesnya hanya ke pengguna dan aplikasi klien yang berwenang. API web yang Anda buat menggunakan izin yang didelegasikan (cakupan) dan izin aplikasi (peran aplikasi).
Di tutorial ini, Anda akan:
- Membangun API web ASP.NET Core
- Mengonfigurasi API web untuk menggunakan detail pendaftaran aplikasi Microsoft Entra
- Melindungi titik akhir API web Anda
- Jalankan API web untuk memastikan api mendengarkan permintaan HTTP
Prasyarat
- Jika Anda belum melakukannya, selesaikan langkah-langkah di Mulai Cepat: Panggil API web yang dilindungi oleh platform identitas Microsoft. Anda tidak perlu mengkloning dan menjalankan sampel kode, tetapi pastikan Anda memiliki yang berikut:
- Detail pendaftaran aplikasi API web dari pusat admin Microsoft Entra, termasuk ID klien dan ID penyewa.
- ToDoList.Read dan ToDoList.ReadWrite sebagai izin (cakupan) yang didelegasikan yang disediakan oleh API Web
- ToDoList.Read.All dan ToDoList.ReadWrite.All sebagai izin aplikasi (peran aplikasi) yang diekspos oleh API Web
- .NET 8.0 SDK atau yang lebih baru.
- Visual Studio Code atau editor kode lainnya.
Membuat proyek API web ASP.NET Core baru
Untuk membuat proyek API web ASP.NET Core minimal, ikuti langkah-langkah berikut:
Buka terminal Anda di Visual Studio Code atau editor kode lainnya dan navigasikan ke direktori tempat Anda ingin membuat proyek.
Jalankan perintah berikut pada .NET CLI atau alat baris perintah lainnya.
dotnet new web -o TodoListApi cd TodoListApi
Pilih Ya saat kotak dialog menanyakan apakah Anda ingin mempercayai penulis.
Pilih Ya Saat kotak dialog menanyakan apakah Anda ingin menambahkan aset yang diperlukan ke proyek.
Menginstal paket yang diperlukan
Untuk membangun, melindungi, dan menguji API web ASP.NET Core, Anda perlu menginstal paket berikut:
-
Microsoft.EntityFrameworkCore.InMemory
- Paket yang memungkinkan Anda menggunakan Entity Framework Core dengan database dalam memori. Ini berguna untuk tujuan pengujian tetapi tidak dirancang untuk penggunaan produksi. -
Microsoft.Identity.Web
- sekumpulan pustaka ASP.NET Core yang menyederhanakan penambahan dukungan autentikasi dan otorisasi ke aplikasi web dan API web yang terintegrasi dengan platform identitas Microsoft.
Untuk menginstal paket, gunakan:
dotnet add package Microsoft.EntityFrameworkCore.InMemory
dotnet add package Microsoft.Identity.Web
Mengonfigurasi detail pendaftaran aplikasi
Buka file appsettings.json di folder aplikasi Anda dan tambahkan detail pendaftaran aplikasi yang Anda rekam setelah mendaftarkan API web.
{
"AzureAd": {
"Instance": "Enter_the_Authority_URL_Here",
"TenantId": "Enter_the_Tenant_Id_Here",
"ClientId": "Enter_the_Application_Id_Here"
},
"Logging": {...},
"AllowedHosts": "*"
}
Ganti tempat penampung berikut seperti yang diperlihatkan:
- Ganti
Enter_the_Application_Id_Here
dengan ID aplikasi (klien) Anda. - Ganti
Enter_the_Tenant_Id_Here
dengan ID Direktori (penyewa) Anda. - Ganti
Enter_the_Authority_URL_Here
dengan URL Otoritas Anda, seperti yang dijelaskan di bagian berikutnya.
URL Otoritas untuk aplikasi Anda
URL otoritas menentukan direktori tempat Microsoft Authentication Library (MSAL) dapat meminta token. Anda membuatnya secara berbeda di penyewa tenaga kerja dan eksternal, seperti yang ditunjukkan:
- penyewa Workforce
- penyewa eksternal
//Instance for workforce tenant
Instance: "https://login.microsoftonline.com/"
Menggunakan domain URL kustom (Opsional)
Domain URL kustom tidak didukung di penyewa tenaga kerja.
Menambahkan izin
Semua API harus menerbitkan minimal satu cakupan, juga disebut izin yang didelegasikan, agar aplikasi klien mendapatkan token akses bagi pengguna dengan sukses. APIs juga harus menerbitkan minimal satu peran aplikasi, yang juga disebut izin aplikasi, agar aplikasi klien dapat memperoleh token akses atas nama mereka sendiri, yaitu, ketika mereka tidak masuk sebagai pengguna.
Kami menentukan izin ini dalam file appsettings.json. Dalam tutorial ini, Anda mendaftarkan izin yang didelegasikan dan aplikasi berikut:
- Izin yang didelegasikan:ToDoList.Read dan ToDoList.ReadWrite.
- Izin aplikasi:ToDoList.Read.All dan ToDoList.ReadWrite.All.
Saat aplikasi pengguna atau klien memanggil API web, hanya klien dengan cakupan atau izin ini yang diizinkan untuk mengakses titik akhir yang dilindungi.
{
"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": "*"
}
Menerapkan autentikasi dan otorisasi di API
Untuk mengonfigurasi autentikasi dan otorisasi, buka file program.cs
dan ganti isinya cuplikan kode berikut:
Menambahkan skema autentikasi
Dalam API ini, kami menggunakan skema JSON Web Token (JWT) Bearer sebagai mekanisme autentikasi default. Gunakan metode AddAuthentication
untuk mendaftarkan skema pembawa 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);
Membuat model aplikasi Anda
Di folder akar proyek, buat folder bernama Model. Navigasikan ke folder Model dan buat file bernama ToDo.cs
lalu tambahkan kode berikut.
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;
}
Kode sebelumnya membuat model yang disebut ToDo. Model ini mewakili data yang dikelola aplikasi.
Tambahkan konteks database
Selanjutnya, kami menentukan kelas konteks database, yang mengoordinasikan fungsionalitas Kerangka Kerja Entitas untuk model data. Kelas ini mewarisi dari kelas Microsoft.EntityFrameworkCore.DbContext yang mengelola interaksi antara aplikasi dan database. Untuk menambahkan konteks database, ikuti langkah-langkah berikut:
Buat folder bernama DbContext di folder akar proyek Anda.
Navigasikan ke folder DbContext dan buat file bernama
ToDoContext.cs
lalu tambahkan kode berikut: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; } }
Buka file Program.cs di folder akar proyek Anda dan perbarui dengan kode berikut:
// 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"));
Dalam cuplikan kode sebelumnya, kami mendaftarkan Konteks DB sebagai layanan terlingkup di penyedia layanan aplikasi ASP.NET Core (juga dikenal sebagai, kontainer injeksi dependensi). Anda juga mengonfigurasi ToDoContext
kelas untuk menggunakan database dalam memori untuk TODo List API.
Menyiapkan pengontrol
Pengontrol biasanya menerapkan tindakan Buat, Baca, Perbarui, dan Hapus (CRUD) untuk mengelola sumber daya. Karena tutorial ini lebih berfokus pada melindungi titik akhir API, kami hanya menerapkan dua item tindakan di pengontrol. Tindakan Baca semua untuk mengambil semua item To-Do dan tindakan Buat untuk menambahkan item To-Do baru. Ikuti langkah-langkah ini untuk menambahkan pengontrol ke proyek Anda:
Navigasi ke folder akar proyek Anda dan buat folder bernama Pengontrol.
Buat file bernama
ToDoListController.cs
di dalam folder Pengontrol dan tambahkan kode pelat boiler berikut:
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(){...}
}
Menambahkan kode ke pengontrol
Bagian ini menjelaskan cara menambahkan kode ke pengontrol yang telah disusun di bagian sebelumnya. Fokus di sini adalah melindungi API, bukan membangunnya.
Impor paket yang diperlukan: Paket
Microsoft.Identity.Web
ini adalah pembungkus di sekitar MSAL.NET yang membantu kami dengan mudah menangani logika autentikasi seperti menangani validasi token. Untuk memastikan bahwa titik akhir kami memerlukan otorisasi, kami menggunakan paket bawaanMicrosoft.AspNetCore.Authorization
.Karena kami memberikan izin agar API ini dipanggil baik menggunakan izin yang didelegasikan atas nama pengguna atau izin aplikasi di mana klien memanggil sebagai dirinya sendiri dan bukan atas nama pengguna, penting untuk mengetahui apakah panggilan dilakukan oleh aplikasi atas nama sendiri. Cara term mudah untuk melakukan ini adalah dengan menemukan apakah token akses berisi
idtyp
klaim opsional. Klaim iniidtyp
adalah cara termudah bagi API untuk menentukan apakah token adalah token aplikasi atau token aplikasi + pengguna. Sebaiknya aktifkanidtyp
klaim opsional.Jika klaim
idtyp
tidak diaktifkan, Anda dapat menggunakan klaimroles
danscp
untuk menentukan apakah token akses adalah token aplikasi atau token aplikasi dan pengguna. Token akses yang dikeluarkan oleh ID Microsoft Entra memiliki setidaknya salah satu dari dua klaim. Token akses yang dikeluarkan untuk pengguna memilikiscp
klaim. Token akses yang dikeluarkan ke aplikasi memilikiroles
klaim. Token akses yang berisi kedua klaim hanya dikeluarkan untuk pengguna, di manascp
klaim menunjuk izin yang didelegasikan, sementararoles
klaim menunjuk peran pengguna. Token akses yang tidak memenuhi kedua syarat tidak boleh dihormati.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"); } }
Tambahkan fungsi pembantu yang menentukan apakah permintaan yang dibuat berisi izin yang cukup untuk melakukan tindakan yang dimaksudkan. Periksa apakah aplikasi yang membuat permintaan atas nama sendiri atau apakah aplikasi melakukan panggilan atas nama pengguna yang memiliki sumber daya yang diberikan dengan memvalidasi ID pengguna.
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; }
Colokkan definisi izin Anda untuk melindungi rute. Lindungi API Anda dengan menambahkan
[Authorize]
atribut ke kelas pengontrol. Ini memastikan tindakan pengontrol hanya dapat dipanggil jika API dipanggil dengan identitas yang diotorisasi. Definisi izin menentukan jenis izin apa yang diperlukan untuk melakukan tindakan ini.[Authorize] [Route("api/[controller]")] [ApiController] public class ToDoListController: ControllerBase{...}
Tambahkan izin ke titik akhir GET dan POST. Lakukan ini menggunakan metode RequiredScopeOrAppPermission yang merupakan bagian dari namespace Microsoft.Identity.Web.Resource . Anda kemudian meneruskan cakupan dan izin ke metode ini melalui atribut RequiredScopesConfigurationKey dan 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); }
Mengonfigurasi middleware API untuk menggunakan pengontrol
Selanjutnya, kami mengonfigurasi aplikasi untuk mengenali dan menggunakan pengontrol untuk menangani permintaan HTTP.
program.cs
Buka file dan tambahkan kode berikut untuk mendaftarkan layanan pengontrol dalam kontainer injeksi dependensi.
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
Dalam cuplikan kode sebelumnya, AddControllers()
metode ini menyiapkan aplikasi untuk menggunakan pengontrol dengan mendaftarkan layanan yang diperlukan sambil MapControllers()
memetakan rute pengontrol untuk menangani permintaan HTTP masuk.
Jalankan API Anda
Jalankan API Anda untuk memastikan bahwa API berjalan tanpa kesalahan menggunakan perintah dotnet run
. Jika Anda ingin menggunakan protokol HTTPS bahkan selama pengujian, Anda perlu mempercayai sertifikat pengembangan .NET .
Mulai aplikasi dengan mengetik yang berikut ini di terminal:
dotnet run
Output yang mirip dengan berikut ini harus ditampilkan di terminal, yang mengonfirmasi bahwa aplikasi sedang dijalankan di
http://localhost:{port}
dan mendengarkan permintaan.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. ...
Halaman web http://localhost:{host}
menampilkan output yang mirip dengan gambar berikut. Ini karena API dipanggil tanpa autentikasi. Untuk melakukan panggilan resmi, lihat Langkah berikutnya untuk panduan tentang cara mengakses API web yang dilindungi.
Untuk contoh lengkap kode API ini, lihat file sampel .