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.
OAuth2Manager di Windows App SDK memungkinkan aplikasi desktop seperti WinUI 3 melakukan otorisasi OAuth 2.0 dengan mulus di Windows. API OAuth2Manager tidak menyediakan API untuk permintaan implisit dan kredensial kata sandi pemilik sumber daya karena masalah keamanan yang terjadi. Gunakan jenis pemberian kode otorisasi dengan Proof Key for Code Exchange (PKCE). Untuk informasi selengkapnya, lihat PKCE RFC.
Latar belakang OAuth 2.0 untuk aplikasi Windows
Windows Runtime (WinRT) WebAuthenticationBroker, terutama dirancang untuk aplikasi UWP, menghadirkan beberapa tantangan saat digunakan di aplikasi desktop. Masalah utama termasuk dependensi pada ApplicationView, yang tidak kompatibel dengan kerangka kerja aplikasi desktop. Akibatnya, pengembang harus menggunakan solusi yang melibatkan antarmuka interop dan kode tambahan untuk menerapkan fungsionalitas OAuth 2.0 ke WinUI dan aplikasi desktop lainnya.
API OAuth2Manager di Windows App SDK
API OAuth2Manager untuk Windows App SDK menyediakan solusi yang disederhanakan yang memenuhi harapan pengembang. Ini menawarkan kemampuan OAuth 2.0 yang mulus dengan paritas fitur lengkap di semua platform Windows yang didukung oleh Windows App SDK. API baru menghilangkan kebutuhan akan solusi yang rumit dan menyederhanakan proses penggabungan fungsionalitas OAuth 2.0 ke dalam aplikasi desktop.
OAuth2Manager berbeda dari WebAuthenticationBroker di WinRT. Ini mengikuti praktik terbaik OAuth 2.0 lebih tepat - misalnya, dengan menggunakan peramban bawaan pengguna. Praktik terbaik untuk API berasal dari IETF (Internet Engineering Task Force) OAuth 2.0 Authorization Framework RFC 6749, PKCE RFC 7636, dan OAuth 2.0 untuk Native Apps RFC 8252.
Contoh kode OAuth 2.0
Aplikasi sampel WinUI lengkap tersedia di GitHub. Bagian berikut menyediakan cuplikan kode untuk alur OAuth 2.0 yang paling umum menggunakan OAuth2Manager API.
Permintaan kode otorisasi
Contoh berikut menunjukkan cara melakukan permintaan kode otorisasi menggunakan OAuth2Manager di Windows App SDK:
// Get the WindowId for the application window
Microsoft::UI::WindowId parentWindowId = this->AppWindow().Id();
AuthRequestParams authRequestParams = AuthRequestParams::CreateForAuthorizationCodeRequest(L"my_client_id",
Uri(L"my-app:/oauth-callback/"));
authRequestParams.Scope(L"user:email user:birthday");
AuthRequestResult authRequestResult = co_await OAuth2Manager::RequestAuthWithParamsAsync(parentWindowId,
Uri(L"https://my.server.com/oauth/authorize"), authRequestParams);
if (AuthResponse authResponse = authRequestResult.Response())
{
//To obtain the authorization code
//authResponse.Code();
//To obtain the access token
DoTokenExchange(authResponse);
}
else
{
AuthFailure authFailure = authRequestResult.Failure();
NotifyFailure(authFailure.Error(), authFailure.ErrorDescription());
}
tukar kode otorisasi untuk token akses
Contoh berikut menunjukkan cara exchange kode otorisasi untuk token access dengan menggunakan OAuth2Manager.
Untuk klien publik (seperti aplikasi desktop asli) yang menggunakan PKCE, jangan sertakan rahasia klien. Pemverifikasi kode PKCE menyediakan keamanan sebagai gantinya:
AuthResponse authResponse = authRequestResult.Response();
TokenRequestParams tokenRequestParams = TokenRequestParams::CreateForAuthorizationCodeRequest(authResponse);
// For public clients using PKCE, do not include ClientAuthentication
TokenRequestResult tokenRequestResult = co_await OAuth2Manager::RequestTokenAsync(
Uri(L"https://my.server.com/oauth/token"), tokenRequestParams);
if (TokenResponse tokenResponse = tokenRequestResult.Response())
{
String accessToken = tokenResponse.AccessToken();
String tokenType = tokenResponse.TokenType();
// RefreshToken string null/empty when not present
if (String refreshToken = tokenResponse.RefreshToken(); !refreshToken.empty())
{
// ExpiresIn is zero when not present
DateTime expires = winrt::clock::now();
if (String expiresIn = tokenResponse.ExpiresIn(); std::stoi(expiresIn) != 0)
{
expires += std::chrono::seconds(static_cast<int64_t>(std::stoi(expiresIn)));
}
else
{
// Assume a duration of one hour
expires += std::chrono::hours(1);
}
//Schedule a refresh of the access token
myAppState.ScheduleRefreshAt(expires, refreshToken);
}
// Use the access token for resources
DoRequestWithToken(accessToken, tokenType);
}
else
{
TokenFailure tokenFailure = tokenRequestResult.Failure();
NotifyFailure(tokenFailure.Error(), tokenFailure.ErrorDescription());
}
Untuk klien konfidensial (seperti aplikasi web atau layanan) yang memiliki kunci rahasia klien, sertakan parameter ClientAuthentication.
AuthResponse authResponse = authRequestResult.Response();
TokenRequestParams tokenRequestParams = TokenRequestParams::CreateForAuthorizationCodeRequest(authResponse);
ClientAuthentication clientAuth = ClientAuthentication::CreateForBasicAuthorization(L"my_client_id",
L"my_client_secret");
TokenRequestResult tokenRequestResult = co_await OAuth2Manager::RequestTokenAsync(
Uri(L"https://my.server.com/oauth/token"), tokenRequestParams, clientAuth);
// Handle the response as shown in the previous example
Menyegarkan token akses
Contoh berikut menunjukkan cara me-refresh token access dengan menggunakan metode OAuth2ManagerRefreshTokenAsync.
Untuk klien publik yang menggunakan PKCE, hilangkan ClientAuthentication parameter:
TokenRequestParams tokenRequestParams = TokenRequestParams::CreateForRefreshToken(refreshToken);
// For public clients using PKCE, do not include ClientAuthentication
TokenRequestResult tokenRequestResult = co_await OAuth2Manager::RequestTokenAsync(
Uri(L"https://my.server.com/oauth/token"), tokenRequestParams);
if (TokenResponse tokenResponse = tokenRequestResult.Response())
{
UpdateToken(tokenResponse.AccessToken(), tokenResponse.TokenType(), tokenResponse.ExpiresIn());
//Store new refresh token if present
if (String refreshToken = tokenResponse.RefreshToken(); !refreshToken.empty())
{
// ExpiresIn is zero when not present
DateTime expires = winrt::clock::now();
if (String expiresInStr = tokenResponse.ExpiresIn(); !expiresInStr.empty())
{
int expiresIn = std::stoi(expiresInStr);
if (expiresIn != 0)
{
expires += std::chrono::seconds(static_cast<int64_t>(expiresIn));
}
}
else
{
// Assume a duration of one hour
expires += std::chrono::hours(1);
}
//Schedule a refresh of the access token
myAppState.ScheduleRefreshAt(expires, refreshToken);
}
}
else
{
TokenFailure tokenFailure = tokenRequestResult.Failure();
NotifyFailure(tokenFailure.Error(), tokenFailure.ErrorDescription());
}
Untuk klien rahasia yang memiliki rahasia klien, sertakan ClientAuthentication parameter :
TokenRequestParams tokenRequestParams = TokenRequestParams::CreateForRefreshToken(refreshToken);
ClientAuthentication clientAuth = ClientAuthentication::CreateForBasicAuthorization(L"my_client_id",
L"my_client_secret");
TokenRequestResult tokenRequestResult = co_await OAuth2Manager::RequestTokenAsync(
Uri(L"https://my.server.com/oauth/token"), tokenRequestParams, clientAuth);
// Handle the response as shown in the previous example
Menyelesaikan permintaan otorisasi
Untuk menyelesaikan permintaan otorisasi dari aktivasi protokol, aplikasi Anda harus menangani peristiwa AppInstance.Activated . Kejadian ini diperlukan saat aplikasi Anda memiliki logika pengalihan kustom. Contoh lengkap tersedia pada GitHub.
Gunakan kode berikut:
void App::OnActivated(const IActivatedEventArgs& args)
{
if (args.Kind() == ActivationKind::Protocol)
{
auto protocolArgs = args.as<ProtocolActivatedEventArgs>();
if (OAuth2Manager::CompleteAuthRequest(protocolArgs.Uri()))
{
TerminateCurrentProcess();
}
DisplayUnhandledMessageToUser();
}
}
Konten terkait
- WebAuthenticationBroker
- OAuth2Manager
- PKCE RFC 7636
Windows developer