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.
Artikel ini memberikan gambaran umum mengenai berbagai jenis kesalahan dan rekomendasi untuk menangani kesalahan umum saat masuk.
Dasar-dasar penanganan kesalahan MSAL
Pengecualian dalam Pustaka Autentikasi Microsoft (MSAL) ditujukan bagi pengembang aplikasi untuk memecahkan masalah, bukan untuk ditampilkan kepada pengguna akhir. Pesan pengecualian tidak dilokalkan.
Saat memproses pengecualian dan kesalahan, Anda dapat menggunakan jenis pengecualian itu sendiri dan kode kesalahan untuk membedakan antara pengecualian. Untuk daftar kode kesalahan, lihat Microsoft Entra kode kesalahan autentikasi dan otorisasi.
Selama pengalaman masuk, Anda mungkin mengalami kesalahan tentang persetujuan, Akses Bersyarat (MFA, Manajemen Perangkat, Pembatasan berbasis lokasi), penerbitan dan penukaran token, dan properti pengguna.
Bagian berikut ini menyediakan detail selengkapnya tentang penanganan kesalahan untuk aplikasi Anda.
Penanganan kesalahan dalam MSAL.NET
Jenis pengecualian
MsalClientException dilemparkan ketika pustaka itu sendiri mendeteksi status kesalahan, seperti konfigurasi yang buruk.
MsalServiceException dilemparkan ketika Penyedia Identitas (Microsoft Entra ID) mengembalikan kesalahan. Ini adalah terjemahan kesalahan server.
MsalUIRequiredException adalah jenis MsalServiceException dan menunjukkan bahwa interaksi pengguna diperlukan. Misalnya, ketika autentikasi multifaktor (MFA) diperlukan atau ketika pengguna mengubah kata sandi mereka dan token tidak dapat diperoleh secara diam-diam.
Memproses pengecualian
Saat memproses eksepsi .NET, Anda dapat menggunakan tipe eksepsi itu sendiri dan anggota ErrorCode untuk membedakan antar eksepsi.
ErrorCode nilai adalah konstanta jenis MsalError.
Anda juga dapat melihat bidang MsalClientException, MsalServiceException, dan MsalUIRequiredException.
Jika MsalServiceException dilemparkan, coba Kode kesalahan autentikasi dan otorisasi untuk melihat apakah kode tercantum di sana.
Jika MsalUIRequiredException dilemparkan, itu adalah indikasi bahwa alur interaktif perlu terjadi bagi pengguna untuk menyelesaikan masalah. Di aplikasi klien publik seperti desktop dan aplikasi seluler, ini diselesaikan dengan memanggil AcquireTokenInteractive, yang menampilkan browser. Di aplikasi klien rahasia, aplikasi web harus mengalihkan pengguna ke halaman otorisasi, dan API web harus mengembalikan kode status HTTP dan header yang menunjukkan kegagalan autentikasi (401 Tidak Sah dan header WWW-Authenticate).
Pengecualian .NET umum
Berikut adalah pengecualian umum yang mungkin dilemparkan dan beberapa kemungkinan mitigasi:
| Pengecualian | Kode kesalahan | Mitigation |
|---|---|---|
| MsalUiRequiredException | AADSTS65001: Pengguna atau administrator belum menyetujui penggunaan aplikasi dengan ID '{appId}' bernama '{appName}'. Kirim permintaan otorisasi interaktif untuk pengguna dan sumber daya ini. | Dapatkan persetujuan pengguna terlebih dahulu. Jika Anda tidak menggunakan .NET Core (yang tidak memiliki antarmuka pengguna Web), panggil (sekali saja) AcquireTokenInteractive. Jika Anda menggunakan inti .NET atau tidak ingin melakukan AcquireTokenInteractive, pengguna dapat menavigasi ke URL untuk memberikan persetujuan: https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={clientId}&response_type=code&scope=user.read. untuk memanggil AcquireTokenInteractive: app.AcquireTokenInteractive(scopes).WithAccount(account).WithClaims(ex.Claims).ExecuteAsync(); |
| MsalUiRequiredException | AADSTS50079: Pengguna diharuskan menggunakan autentikasi multifaktor (MFA). | Tidak ada mitigasi. Jika MFA dikonfigurasi untuk tenant Anda dan Microsoft Entra ID memutuskan untuk menerapkannya, gunakan alur interaktif sebagai cadangan, seperti AcquireTokenInteractive. |
| MsalServiceException | AADSTS90010: Jenis grant tidak didukung pada endpoint /common atau /consumers. Gunakan /organizations atau titik akhir khusus tenant. Anda menggunakan /common. | Seperti yang dijelaskan dalam pesan dari Microsoft Entra ID, otoritas harus memiliki penyewa atau sebaliknya /organisasi. |
| MsalServiceException | AADSTS70002: Isi permintaan harus berisi parameter berikut: client_secret or client_assertion. |
Pengecualian ini dapat dilemparkan jika aplikasi Anda tidak terdaftar sebagai aplikasi klien publik di Microsoft Entra ID. Di pusat admin Microsoft Entra, edit manifes untuk aplikasi Anda dan atur allowPublicClient ke true. |
| MsalClientException |
unknown_user Message: Tidak dapat mengidentifikasi pengguna yang masuk |
Pustaka ini tidak dapat membuat kueri terhadap pengguna Windows yang saat ini masuk, atau pengguna tersebut tidak tergabung ke Direktori Aktif atau Microsoft Entra (pengguna yang tergabung ke tempat kerja tidak didukung). Mitigasi: Terapkan logika Anda sendiri untuk mengambil nama pengguna (misalnya, john@contoso.com) dan gunakan AcquireTokenByIntegratedWindowsAuth formulir yang mengambil nama pengguna. |
| MsalClientException | integrated_windows_auth_not_supported_managed_user | Metode ini bergantung pada protokol yang diekspos oleh Direktori Aktif (AD). Jika pengguna dibuat di Microsoft Entra ID tanpa dukungan AD (pengguna "terkelola"), metode ini gagal. Pengguna yang dibuat dalam AD dan didukung oleh Microsoft Entra ID ("pengguna federasi") dapat memanfaatkan metode autentikasi non-interaktif ini. Mitigasi: Gunakan autentikasi interaktif. |
MsalUiRequiredException
Salah satu kode status umum yang dikembalikan dari MSAL.NET saat memanggil AcquireTokenSilent() adalah MsalError.InvalidGrantError. Kode status ini berarti bahwa aplikasi harus memanggil pustaka autentikasi lagi, tetapi dalam mode interaktif (AcquireTokenInteractive atau AcquireTokenByDeviceCodeFlow untuk aplikasi klien publik, memang memiliki tantangan di aplikasi Web). Ini karena interaksi pengguna tambahan diperlukan sebelum token autentikasi dapat dikeluarkan.
Sebagian besar waktu ketika AcquireTokenSilent gagal, itu karena cache token tidak memiliki token yang cocok dengan permintaan Anda. Token akses kedaluwarsa dalam 1 jam, dan AcquireTokenSilent mencoba mengambil yang baru berdasarkan token refresh (dalam istilah OAuth2, ini adalah alur "Refresh Token'). Alur ini juga dapat gagal karena berbagai alasan, misalnya jika admin penyewa mengonfigurasi kebijakan masuk yang lebih ketat.
Interaksi bertujuan meminta pengguna melakukan tindakan. Beberapa kondisi tersebut mudah diselesaikan pengguna (misalnya, menerima Ketentuan Penggunaan dengan satu klik), dan beberapa tidak dapat diselesaikan dengan konfigurasi saat ini (misalnya, mesin yang dimaksud perlu terhubung ke jaringan perusahaan tertentu). Beberapa membantu pengguna menyiapkan autentikasi multifaktor, atau menginstal Microsoft Authenticator di perangkat mereka.
MsalUiRequiredException enumerasi klasifikasi
MSAL menyediakan field Classification, yang dapat dibaca untuk memberikan pengalaman pengguna yang lebih baik. Misalnya, untuk memberi tahu pengguna bahwa kata sandi mereka kedaluwarsa atau bahwa mereka perlu memberikan persetujuan untuk menggunakan beberapa sumber daya. Nilai yang didukung adalah bagian UiRequiredExceptionClassification dari enum:
| Classification | Meaning | Penanganan yang direkomendasikan |
|---|---|---|
| BasicAction | Kondisi dapat diselesaikan dengan interaksi pengguna selama alur autentikasi interaktif. | Panggil AcquireTokenInteractively(). |
| Tindakan Tambahan | Kondisi dapat diselesaikan dengan interaksi remedial tambahan dengan sistem, di luar alur autentikasi interaktif. | Panggil AcquireTokenInteractively() untuk menampilkan pesan yang menjelaskan tindakan perbaikan. Aplikasi panggilan dapat memilih untuk menyembunyikan alur yang memerlukan additional_action jika pengguna tidak mungkin menyelesaikan tindakan perbaikan. |
| MessageOnly | Kondisi tidak dapat diselesaikan saat ini. Meluncurkan alur autentikasi interaktif akan menampilkan pesan yang menjelaskan kondisi. | Panggil AcquireTokenInteractively() untuk menampilkan pesan yang menjelaskan kondisi. AcquireTokenInteractively() akan mengembalikan kesalahan UserCanceled setelah pengguna membaca pesan dan menutup jendela. Aplikasi pemanggil dapat memilih untuk menyembunyikan alur yang menghasilkan message_only jika pengguna kemungkinan tidak akan memperoleh manfaat dari pesan tersebut. |
| Persetujuan Diperlukan | Persetujuan pengguna hilang, atau telah dicabut. | Panggil AcquireTokenInteractively() agar pengguna memberikan persetujuan. |
| Kata sandi pengguna telah kedaluwarsa | Kata sandi pengguna telah kedaluwarsa. | Panggil AcquireTokenInteractively() sehingga pengguna dapat mengatur ulang kata sandi mereka. |
| PromptNeverFailed | Autentikasi Interaktif dipanggil dengan parameter prompt=never, sehingga MSAL dipaksa mengandalkan kukis browser serta tidak menampilkan jendela browser. Ini gagal. | Panggil AcquireTokenInteractively() tanpa Prompt.None |
| AcquireTokenSilentFailed | MSAL SDK tidak memiliki informasi yang cukup untuk mengambil token dari cache. Ini bisa karena tidak ada token di cache atau akun tidak ditemukan. Pesan kesalahan memiliki detail lebih lanjut. | Panggil AcquireTokenInteractively(). |
| Tidak | Tidak ada detail lebih lanjut yang disediakan. Kondisi dapat diatasi oleh interaksi pengguna selama alur autentikasi interaktif. | Panggil AcquireTokenInteractively(). |
contoh kode .NET
AuthenticationResult res;
try
{
res = await application.AcquireTokenSilent(scopes, account)
.ExecuteAsync();
}
catch (MsalUiRequiredException ex) when (ex.ErrorCode == MsalError.InvalidGrantError)
{
switch (ex.Classification)
{
case UiRequiredExceptionClassification.None:
break;
case UiRequiredExceptionClassification.MessageOnly:
// You might want to call AcquireTokenInteractive(). Azure AD will show a message
// that explains the condition. AcquireTokenInteractively() will return UserCanceled error
// after the user reads the message and closes the window. The calling application may choose
// to hide features or data that result in message_only if the user is unlikely to benefit
// from the message
try
{
res = await application.AcquireTokenInteractive(scopes).ExecuteAsync();
}
catch (MsalClientException ex2) when (ex2.ErrorCode == MsalError.AuthenticationCanceledError)
{
// Do nothing. The user has seen the message
}
break;
case UiRequiredExceptionClassification.BasicAction:
// Call AcquireTokenInteractive() so that the user can, for instance accept terms
// and conditions
case UiRequiredExceptionClassification.AdditionalAction:
// You might want to call AcquireTokenInteractive() to show a message that explains the remedial action.
// The calling application may choose to hide flows that require additional_action if the user
// is unlikely to complete the remedial action (even if this means a degraded experience)
case UiRequiredExceptionClassification.ConsentRequired:
// Call AcquireTokenInteractive() for user to give consent.
case UiRequiredExceptionClassification.UserPasswordExpired:
// Call AcquireTokenInteractive() so that user can reset their password
case UiRequiredExceptionClassification.PromptNeverFailed:
// You used WithPrompt(Prompt.Never) and this failed
case UiRequiredExceptionClassification.AcquireTokenSilentFailed:
default:
// May be resolved by user interaction during the interactive authentication flow.
res = await application.AcquireTokenInteractive(scopes)
.ExecuteAsync(); break;
}
}
Tantangan Akses Bersyarat dan Klaim
Saat mendapatkan token secara diam-diam, aplikasi Anda mungkin menerima kesalahan ketika tantangan klaim Akses Bersyarat seperti kebijakan MFA diperlukan oleh API yang coba Anda akses.
Pola untuk menangani kesalahan ini adalah memperoleh token secara interaktif menggunakan MSAL. Ini meminta pengguna dan memberi mereka kesempatan untuk memenuhi kebijakan Akses Bersyarat yang diperlukan.
Dalam kasus tertentu saat memanggil API yang memerlukan Akses Bersyarat, Anda dapat menerima tantangan klaim dalam kesalahan dari API. Misalnya jika kebijakan Akses Bersyarat adalah memiliki perangkat terkelola (Intune) kesalahan akan menjadi sesuatu seperti AADSTS53000: Perangkat Anda harus dikelola untuk mengakses sumber daya ini atau sesuatu yang serupa. Dalam hal ini, Anda dapat meneruskan klaim dalam panggilan token akuisisi sehingga pengguna diminta untuk memenuhi kebijakan yang sesuai.
Saat memanggil API yang memerlukan Akses Bersyarat dari MSAL.NET, aplikasi Anda perlu menangani pengecualian tantangan klaim. Ini muncul sebagai MsalServiceException di mana properti Klaim tidak akan kosong.
Untuk menangani tantangan klaim, gunakan WithClaims(String).
Mencoba kembali setelah kesalahan dan pengecualian
Anda diharapkan untuk mengimplementasikan kebijakan percobaan ulang Anda sendiri saat memanggil MSAL. MSAL melakukan panggilan HTTP ke layanan Microsoft Entra, dan terkadang kegagalan dapat terjadi. Misalnya jaringan dapat mati atau server kelebihan beban.
HTTP 429
Ketika Server Token Layanan (STS) kelebihan beban karena terlalu banyak permintaan, server akan mengembalikan kesalahan HTTP 429 beserta petunjuk tentang berapa lama lagi Anda dapat mencoba kembali dalam bidang respons Retry-After.
Kode kesalahan HTTP 500-600
MSAL.NET menerapkan mekanisme coba lagi-sekali sederhana untuk kesalahan dengan kode kesalahan HTTP 500-600.
MsalServiceException muncul System.Net.Http.Headers.HttpResponseHeaders sebagai properti namedHeaders. Anda dapat menggunakan informasi tambahan dari kode kesalahan untuk meningkatkan keandalan aplikasi Anda. Dalam kasus yang dijelaskan, Anda dapat menggunakan RetryAfter properti (jenis RetryConditionHeaderValue) dan menghitung kapan harus mencoba kembali.
Berikut adalah contoh untuk aplikasi daemon menggunakan alur kredensial klien. Anda dapat menyesuaikan ini dengan salah satu metode untuk memperoleh token.
bool retry = false;
do
{
TimeSpan? delay;
try
{
result = await publicClientApplication.AcquireTokenForClient(scopes, account).ExecuteAsync();
}
catch (MsalServiceException serviceException)
{
if (serviceException.ErrorCode == "temporarily_unavailable")
{
RetryConditionHeaderValue retryAfter = serviceException.Headers.RetryAfter;
if (retryAfter.Delta.HasValue)
{
delay = retryAfter.Delta;
}
else if (retryAfter.Date.HasValue)
{
delay = (retryAfter.Date.Value – DateTimeOffset.Now).TotalMilliseconds;
}
}
}
// . . .
if (delay.HasValue)
{
Thread.Sleep((int)delay.Value.TotalMilliseconds); // sleep or other
retry = true;
}
} while (retry);
Langkah berikutnya
Pertimbangkan untuk mengaktifkan pencatatan log di MSAL.NET guna membantu Anda mendiagnosis dan melakukan debug terhadap masalah.