Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Prerequisites
-
SDK d'application Windows canal de mise en production expérimentale : OAuth2Manager n’est pas disponible dans le canal stable. Installez une version préliminaire avec un
Microsoft.WindowsAppSDKsuffixe (sélectionnez-experimentaldans NuGet). Pour plus d’informations, consultez Configurer votre environnement de développement.
Overview
OAuth2Manager dans SDK d'application Windows permet aux applications de bureau telles que WinUI 3 d’effectuer l’autorisation OAuth 2.0 sur Windows. L’API OAuth2Manager ne fournit pas d’API pour les informations d’identification de mot de passe de la demande implicite et du propriétaire de la ressource en raison des problèmes de sécurité qui impliquent. Utilisez le type d’octroi de code d’autorisation avec la clé de preuve pour l'échange de code (PKCE). Pour plus d'informations, consultez le RFC PKCE.
Note
OAuth2Manager est conçu pour les flux OAuth 2.0 généraux avec n’importe quel fournisseur d’identité (GitHub, Google, personnalisé, etc.) et utilise toujours le navigateur système pour l’étape d’autorisation. Si vous souhaitez spécifiquement vous connecter avec des comptes Microsoft ou des comptes Microsoft Entra ID (professionnel/scolaire) avec silent SSO — à l’aide du compte déjà connecté à Windows, sans invite de navigateur : utilisez MSAL.NET avec le répartiteur du gestionnaire de comptes web (WAM) à la place. Le Gestionnaire de comptes web offre également l'intégration avec Windows Hello et le support de l'accès conditionnel, que OAuth2Manager ne supporte pas.
API OAuth2Manager dans SDK d'application Windows
L’API OAuth2Manager pour SDK d'application Windows gère les flux de code d’autorisation OAuth 2.0 avec PKCE pour les applications de bureau. Il fonctionne sur toutes les plateformes Windows prises en charge par SDK d'application Windows, fournissant une interface d’acquisition de jeton cohérente sans nécessiter de solutions de contournement basées sur un navigateur tiers.
OAuth2Manager est différent de WebAuthenticationBroker dans WinRT. Il suit les meilleures pratiques OAuth 2.0 plus étroitement , par exemple en utilisant le navigateur par défaut de l’utilisateur. Les meilleures pratiques pour l’API proviennent de l’IETF (Internet Engineering Task Force) OAuth 2.0 Authorization Framework RFC 6749, PKCE RFC 7636 et OAuth 2.0 for Native Apps RFC 8252.
Exemples de code OAuth 2.0
Un exemple d’application WinUI complet est disponible sur GitHub. Les sections suivantes fournissent des extraits de code pour les flux OAuth 2.0 les plus courants à l’aide de l’API OAuth2Manager .
Demande de code d’autorisation
L’exemple suivant montre comment effectuer une demande de code d’autorisation à l’aide du OAuth2Manager dans SDK d'application Windows :
// 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());
}
Échanger le code d’autorisation pour le jeton d’accès
L’exemple suivant montre comment échanger un code d’autorisation pour un jeton d'accès à l’aide de l'OAuth2Manager.
Pour les clients publics (comme les applications de bureau natives) qui utilisent PKCE, n’incluez pas de clé secrète client. Le vérificateur de code PKCE fournit plutôt la sécurité :
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());
}
Important
Les applications de bureau sont des clients publics et ne doivent pas incorporer de secrets clients. Le modèle client confidentiel ci-dessous s’applique uniquement aux composants côté serveur (applications web, API, services principaux) qui peuvent stocker en toute sécurité les informations d’identification. Une application de bureau native ne peut pas protéger un secret client contre l’extraction : utilisez plutôt le modèle client public avec PKCE indiqué ci-dessus. Si votre architecture nécessite une clé secrète client pour l’échange de jetons, effectuez cet échange sur votre service principal, et non dans l’application de bureau.
Pour les clients confidential (tels que web apps ou services) qui ont une clé secrète client, incluez le paramètre 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
Actualiser un jeton de access
L'exemple suivant montre comment actualiser un jeton access à l'aide de la méthode OAuth2ManagerRefreshTokenAsync.
Pour les clients publics qui utilisent PKCE, omettez le ClientAuthentication paramètre :
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());
}
Pour les clients confidentiels qui ont une clé secrète client, incluez le ClientAuthentication paramètre :
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
Effectuer une demande d’autorisation
Pour effectuer une demande d’autorisation à partir d’une activation de protocole, votre application doit gérer l’événement AppInstance.Activated . Cet événement est requis lorsque votre application a une logique de redirection personnalisée. Un exemple complet est disponible sur GitHub.
Utilisez le code suivant :
void App::OnActivated(const IActivatedEventArgs& args)
{
if (args.Kind() == ActivationKind::Protocol)
{
auto protocolArgs = args.as<ProtocolActivatedEventArgs>();
if (OAuth2Manager::CompleteAuthRequest(protocolArgs.Uri()))
{
TerminateCurrentProcess();
}
DisplayUnhandledMessageToUser();
}
}
Contenu connexe
Windows developer