Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Der OAuth2Manager in Windows App SDK ermöglicht Desktopanwendungen wie WinUI 3 die nahtlose OAuth 2.0-Autorisierung unter Windows. Die OAuth2Manager-API stellt keine APIs für die impliziten Anforderungs- und Ressourcenbesitzer-Kennwortanmeldeinformationen aufgrund der sicherheitsrelevanten Bedenken bereit. Verwenden Sie den Autorisierungscode-Grant-Typ mit dem Proof Key für Code Exchange (PKCE). Weitere Informationen finden Sie unter PKCE RFC.
OAuth 2.0-Hintergrund für Windows-Apps
Die Windows-Runtime (WinRT) WebAuthenticationBroker, die hauptsächlich für UWP-Apps entwickelt wurde, stellt bei der Verwendung in Desktop-Apps mehrere Herausforderungen dar. Wichtige Probleme sind die Abhängigkeit von ApplicationView, die nicht mit Desktop-App-Frameworks kompatibel ist. Daher müssen Entwickler auf Problemumgehungen zurückgreifen, die Interopschnittstellen und zusätzlichen Code umfassen, um OAuth 2.0-Funktionen in WinUI 3 und andere Desktop-Apps zu implementieren.
OAuth2Manager-API im Windows App SDK
Die OAuth2Manager-API für windows App SDK bietet eine optimierte Lösung, die den Erwartungen von Entwicklern entspricht. Es bietet nahtlose OAuth 2.0-Funktionen mit vollständiger Funktionsparität auf allen Windows-Plattformen, die vom Windows App SDK unterstützt werden. Die neue API beseitigt die Notwendigkeit umständlicher Problemumgehungen und vereinfacht den Prozess der Integration von OAuth 2.0-Funktionen in Desktop-Apps.
Der OAuth2Manager unterscheidet sich vom WebAuthenticationBroker in WinRT. Es folgt den bewährten OAuth 2.0-Methoden genauer , z. B. mithilfe des Standardbrowsers des Benutzers. Die bewährten Methoden für die API stammen aus dem IETF (Internet Engineering Task Force) OAuth 2.0 Authorization Framework RFC 6749, PKCE RFC 7636 und OAuth 2.0 für Native Apps RFC 8252.
OAuth 2.0-Codebeispiele
Eine vollständige WinUI 3-Beispiel-App ist auf GitHub verfügbar. In den folgenden Abschnitten werden Codeausschnitte für die am häufigsten verwendeten OAuth 2.0-Flüsse mithilfe der OAuth2Manager-API bereitgestellt.
Autorisierungscodeanforderung
Im folgenden Beispiel wird veranschaulicht, wie Eine Autorisierungscodeanforderung mithilfe des OAuth2Manager in Windows App SDK ausgeführt wird:
// 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());
}
Exchange-Autorisierungscode für Zugriffstoken
Das folgende Beispiel zeigt, wie Sie mithilfe des OAuth2Managers einen Autorisierungscode für ein Zugriffstoken austauschen.
Für öffentliche Clients (z. B. native Desktop-Apps), die PKCE verwenden, schließen Sie keinen geheimen Clientschlüssel ein. Die PKCE-Codeüberprüfung stellt stattdessen die Sicherheit bereit:
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());
}
Schließen Sie für vertrauliche Clients (z. B. Web-Apps oder Dienste) mit einem geheimen Clientschlüssel den ClientAuthentication Parameter ein:
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
Aktualisieren eines Zugriffstokens
Das folgende Beispiel zeigt, wie Sie ein Zugriffstoken mithilfe der RefreshTokenAsync-Methode von OAuth2Manager aktualisieren.
Für öffentliche Clients , die PKCE verwenden, lassen Sie den ClientAuthentication Parameter aus:
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());
}
Fügen Sie für vertrauliche Clients mit einem geheimen Clientschlüssel den ClientAuthentication Parameter ein:
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
Abschließen einer Autorisierungsanforderung
Um eine Autorisierungsanforderung über eine Protokollaktivierung abzuschließen, sollte Ihre App das Ereignis "AppInstance.Activated " behandeln. Dieses Ereignis ist erforderlich, wenn Ihre App über eine benutzerdefinierte Umleitungslogik verfügt. Ein vollständiges Beispiel ist auf GitHub verfügbar.
Verwenden Sie den folgenden Code:
void App::OnActivated(const IActivatedEventArgs& args)
{
if (args.Kind() == ActivationKind::Protocol)
{
auto protocolArgs = args.as<ProtocolActivatedEventArgs>();
if (OAuth2Manager::CompleteAuthRequest(protocolArgs.Uri()))
{
TerminateCurrentProcess();
}
DisplayUnhandledMessageToUser();
}
}
Verwandte Inhalte
Windows developer