Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
OAuth2Manager w Zestaw SDK do aplikacji systemu Windows umożliwia aplikacjom komputerowym, takim jak WinUI 3 bezproblemowe wykonywanie autoryzacji OAuth 2.0 na Windows. API OAuth2Manager nie udostępnia API dla implicitnych żądań i poświadczeń hasła właściciela zasobu ze względu na względy bezpieczeństwa. Użyj typu przyznania kodu autoryzacji z dowodem klucza wymiany kodu (PKCE). Aby uzyskać więcej informacji, zobacz PKCE RFC.
Uwaga / Notatka
OAuth2Manager jest przeznaczony dla ogólnych przepływów OAuth 2.0 z dowolnym dostawcą tożsamości (GitHub, Google, niestandardowy itp.) i zawsze używa przeglądarki systemowej do kroku autoryzacji. Jeśli chcesz zalogować się korzystając z kont Microsoft albo kont Microsoft Entra ID (służbowych/szkolnych) przy użyciu silent SSO — używając konta, które zostało już zalogowane w systemie Windows, bez monitu przeglądarki — zamiast tego użyj MSAL.NET przy użyciu brokera Menedżera Kont Sieci Web. Menedżer kont sieci Web zapewnia również integrację Windows Hello i obsługę dostępu warunkowego, których nie obsługuje protokół OAuth2Manager.
Interfejs API OAuth2Manager w Zestaw SDK do aplikacji systemu Windows
Interfejs API OAuth2Manager dla Zestaw SDK do aplikacji systemu Windows zapewnia usprawnione rozwiązanie spełniające oczekiwania deweloperów. Oferuje ona bezproblemowe funkcje protokołu OAuth 2.0 z pełną parzystością funkcji na wszystkich platformach Windows obsługiwanych przez Zestaw SDK do aplikacji systemu Windows. Nowy interfejs API eliminuje potrzebę kłopotliwych obejść i upraszcza proces dołączania funkcji OAuth 2.0 do aplikacji klasycznych.
Element OAuth2Manager różni się od elementu WebAuthenticationBroker w środowisku WinRT. Jest to bardziej zgodne z najlepszymi rozwiązaniami protokołu OAuth 2.0 — na przykład przy użyciu domyślnej przeglądarki użytkownika. Najlepsze rozwiązania dotyczące interfejsu API pochodzą z IETF (Internet Engineering Task Force) OAuth 2.0 Authorization Framework RFC 6749, PKCE RFC 7636 i OAuth 2.0 for Native Apps RFC 8252.
Przykłady kodu OAuth 2.0
Pełna przykładowa aplikacja WinUI jest dostępna w GitHub. Poniższe sekcje zawierają fragmenty kodu dla najbardziej typowych przepływów protokołu OAuth 2.0 przy użyciu interfejsu API OAuth2Manager.
Żądanie kodu autoryzacji
W poniższym przykładzie pokazano, jak wykonać żądanie kodu autoryzacji przy użyciu OAuth2Manager w Zestaw SDK do aplikacji systemu 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());
}
kod autoryzacji Exchange tokenu dostępu
W poniższym przykładzie pokazano, jak wymienić kod autoryzacji na token dostępu przy użyciu OAuth2Manager.
W przypadku klientów publicznych, takich jak natywne aplikacje klasyczne, korzystających z PKCE, nie dołączaj tajnego hasła klienta. Zamiast tego, weryfikator kodu PKCE zapewnia zabezpieczenia.
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());
}
W przypadku klientów poufnych (takich jak aplikacje internetowe lub usługi), które mają tajny klucz klienta, dołącz parametr 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
Odśwież token dostępu
W poniższym przykładzie pokazano, jak odświeżyć token dostępu przy użyciu metody OAuth2Manager's RefreshTokenAsync.
W przypadku klientów publicznych korzystających z PKCE pomiń ClientAuthentication parametr :
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());
}
W przypadku poufnych klientów, którzy mają tajny klucz klienta, dołącz parametr ClientAuthentication.
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
Ukończ żądanie autoryzacji
Aby ukończyć żądanie autoryzacji z aktywacji protokołu, aplikacja powinna obsługiwać zdarzenie AppInstance.Activated . To zdarzenie jest wymagane, gdy aplikacja ma niestandardową logikę przekierowania. Pełny przykład jest dostępny w GitHub.
Użyj następującego kodu:
void App::OnActivated(const IActivatedEventArgs& args)
{
if (args.Kind() == ActivationKind::Protocol)
{
auto protocolArgs = args.as<ProtocolActivatedEventArgs>();
if (OAuth2Manager::CompleteAuthRequest(protocolArgs.Uri()))
{
TerminateCurrentProcess();
}
DisplayUnhandledMessageToUser();
}
}