Web Account Manager
In diesem Artikel wird beschrieben, wie Sie die AccountsSettingsPane verwenden, um Ihre Universelle Windows-Plattform (UWP)-App mit externen Identitätsanbietern wie Microsoft oder Facebook mithilfe der Windows 10- und Windows 11 Web Account Manager-APIs zu verbinden. Sie erfahren, wie Sie die Berechtigung eines Benutzers für die Verwendung seines Microsoft-Kontos anfordern, ein Zugriffstoken abrufen und es verwenden, um grundlegende Vorgänge auszuführen (z. B. Profildaten abrufen oder Dateien in sein OneDrive-Konto hochladen). Die Schritte ähneln dem Abrufen der Benutzerberechtigung und des Zugriffs mit jedem Identitätsanbieter, der den Web Account Manager unterstützt.
Hinweis
Ein vollständiges Codebeispiel finden Sie im WebAccountManagement-Beispiel auf GitHub.
Vorbereiten
Erstellen Sie zunächst eine neue, leere App in Visual Studio.
Um eine Verbindung mit Identitätsanbietern herzustellen, müssen Sie Ihre App dem Store zuordnen. Klicken Sie dazu mit der rechten Maustaste auf Ihr Projekt, wählen Sie die Store-/Veröffentlichungs-App>für den Store aus, und folgen Sie den Anweisungen des Assistenten.
Erstellen Sie drittens eine sehr einfache Benutzeroberfläche, die aus einer einfachen XAML-Schaltfläche und zwei Textfeldern besteht.
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Button x:Name="LoginButton" Content="Log in" Click="LoginButton_Click" />
<TextBlock x:Name="UserIdTextBlock"/>
<TextBlock x:Name="UserNameTextBlock"/>
</StackPanel>
Und ein Ereignishandler, der an die Schaltfläche im CodeBehind angefügt ist:
private void LoginButton_Click(object sender, RoutedEventArgs e)
{
}
Fügen Sie schließlich die folgenden Namespaces hinzu, damit Sie sich später keine Gedanken über Referenzprobleme machen müssen:
using System;
using Windows.Security.Authentication.Web.Core;
using Windows.System;
using Windows.UI.ApplicationSettings;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.Data.Json;
using Windows.UI.Xaml.Navigation;
using Windows.Web.Http;
Anzeigen des Bereichs "Konteneinstellungen"
Das System bietet eine integrierte Benutzeroberfläche zum Verwalten von Identitätsanbietern und Webkonten namens AccountsSettingsPane. Sie können es wie folgt anzeigen:
private void LoginButton_Click(object sender, RoutedEventArgs e)
{
AccountsSettingsPane.Show();
}
Wenn Sie Ihre App ausführen und auf die Schaltfläche "Anmelden" klicken, sollte ein leeres Fenster angezeigt werden.
Der Bereich ist leer, da das System nur eine UI-Shell bereitstellt – es liegt an dem Entwickler, den Bereich programmgesteuert mit den Identitätsanbietern aufzufüllen.
Tipp
Optional können Sie ShowAddAccountAsync anstelle von Show verwenden, wodurch eine IAsyncAction zurückgegeben wird, um den Status des Vorgangs abzufragen.
Registrieren für AccountCommandsRequested
Um dem Bereich Befehle hinzuzufügen, registrieren wir zunächst den AccountCommandsRequested-Ereignishandler. Dies weist das System an, unsere Buildlogik auszuführen, wenn der Benutzer aufgefordert wird, den Bereich anzuzeigen (z. B. klickt auf unsere XAML-Schaltfläche).
Überschreiben Sie in Ihrem CodeBehind die Ereignisse "OnNavigatedTo" und "OnNavigatedFrom", und fügen Sie ihnen den folgenden Code hinzu:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
AccountsSettingsPane.GetForCurrentView().AccountCommandsRequested += BuildPaneAsync;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
AccountsSettingsPane.GetForCurrentView().AccountCommandsRequested -= BuildPaneAsync;
}
Benutzer interagieren nicht sehr häufig mit Konten, sodass das Registrieren und Aufheben der Registrierung des Ereignishandlers in dieser Weise dazu beiträgt, Speicherverluste zu verhindern. Auf diese Weise befindet sich Ihr benutzerdefinierter Bereich nur im Arbeitsspeicher, wenn ein Benutzer eine hohe Chance hat, ihn zu fragen (da er sich beispielsweise auf einer Seite "Einstellungen" oder "Anmeldung" befindet).
Erstellen des Bereichs "Kontoeinstellungen"
Die BuildPaneAsync-Methode wird immer aufgerufen, wenn accountsSettingsPane angezeigt wird. Hier fügen wir den Code ein, um die im Bereich angezeigten Befehle anzupassen.
Rufen Sie zunächst eine Verzögerung ab. Dadurch wird dem System mitgeteilt, dass die Anzeige des AccountsSettingsPane verzögert wird , bis die Erstellung abgeschlossen ist.
private async void BuildPaneAsync(AccountsSettingsPane s,
AccountsSettingsPaneCommandsRequestedEventArgs e)
{
var deferral = e.GetDeferral();
deferral.Complete();
}
Rufen Sie als Nächstes einen Anbieter mithilfe der WebAuthenticationCoreManager.FindAccountProviderAsync-Methode ab. Die URL für den Anbieter variiert je nach Anbieter und ist in der Dokumentation des Anbieters zu finden. Für Microsoft-Konten und Azure Active Directory lautet dies "https://login.microsoft.com".
private async void BuildPaneAsync(AccountsSettingsPane s,
AccountsSettingsPaneCommandsRequestedEventArgs e)
{
var deferral = e.GetDeferral();
var msaProvider = await WebAuthenticationCoreManager.FindAccountProviderAsync(
"https://login.microsoft.com", "consumers");
deferral.Complete();
}
Beachten Sie, dass wir auch die Zeichenfolge "consumer" an den optionalen Autoritätsparameter übergeben. Dies liegt daran, dass Microsoft zwei verschiedene Authentifizierungstypen bereitstellt: Microsoft-Konten (MSA) für "Consumer" und Azure Active Directory (AAD) für "Organisationen". Die "Consumer"-Behörde gibt an, dass wir die MSA-Option verwenden möchten. Wenn Sie eine Unternehmens-App entwickeln, verwenden Sie stattdessen die Zeichenfolge "Organisationen".
Fügen Sie schließlich den Anbieter zum AccountsSettingsPane hinzu, indem Sie wie folgt einen neuen WebAccountProviderCommand erstellen:
private async void BuildPaneAsync(AccountsSettingsPane s,
AccountsSettingsPaneCommandsRequestedEventArgs e)
{
var deferral = e.GetDeferral();
var msaProvider = await WebAuthenticationCoreManager.FindAccountProviderAsync(
"https://login.microsoft.com", "consumers");
var command = new WebAccountProviderCommand(msaProvider, GetMsaTokenAsync);
e.WebAccountProviderCommands.Add(command);
deferral.Complete();
}
Die GetMsaToken-Methode, die wir an unseren neuen WebAccountProviderCommand übergeben haben, ist noch nicht vorhanden (das wird im nächsten Schritt erstellt), daher können Sie sie jetzt als leere Methode hinzufügen.
Führen Sie den obigen Code aus, und Ihr Bereich sollte ungefähr wie folgt aussehen:
Anfordern eines Tokens
Sobald die Microsoft-Kontooption im AccountsSettingsPane angezeigt wird, müssen wir behandeln, was passiert, wenn der Benutzer sie auswählt. Wir haben unsere GetMsaToken-Methode registriert, um auszulösen, wenn sich der Benutzer für die Anmeldung mit ihrem Microsoft-Konto entscheidet, sodass wir das Token dort abrufen.
Verwenden Sie zum Abrufen eines Tokens die RequestTokenAsync-Methode wie folgt:
private async void GetMsaTokenAsync(WebAccountProviderCommand command)
{
WebTokenRequest request = new WebTokenRequest(command.WebAccountProvider, "wl.basic");
WebTokenRequestResult result = await WebAuthenticationCoreManager.RequestTokenAsync(request);
}
In diesem Beispiel übergeben wir die Zeichenfolge "wl.basic" an den Bereichsparameter . Der Bereich stellt den Typ der Informationen dar, die Sie vom bereitstellenden Dienst für einen bestimmten Benutzer anfordern. Bestimmte Bereiche bieten nur Zugriff auf die grundlegenden Informationen eines Benutzers, z. B. Name und E-Mail-Adresse, während andere Bereiche möglicherweise Zugriff auf vertrauliche Informationen gewähren, z. B. die Fotos des Benutzers oder den E-Mail-Posteingang. Im Allgemeinen sollte Ihre App den am wenigsten zulässigen Bereich verwenden, der erforderlich ist, um seine Funktion zu erreichen. Dienstanbieter stellen Dokumentationen bereit, in denen Bereiche benötigt werden, um Token für die Verwendung mit ihren Diensten abzurufen.
- Informationen zu Microsoft 365 und Outlook.com Bereichen finden Sie unter Verwenden der Outlook-REST-API (Version 2.0).
- Informationen zu OneDrive-Bereichen finden Sie unter OneDrive-Authentifizierung und -Anmeldung.
Tipp
Wenn Ihre App optional einen Anmeldehinweis (zum Auffüllen des Benutzerfelds mit einer Standard-E-Mail-Adresse) oder eine andere spezielle Eigenschaft im Zusammenhang mit der Anmeldeoberfläche verwendet, listen Sie ihn in der WebTokenRequest.AppProperties-Eigenschaft auf. Dies führt dazu, dass das System die Eigenschaft beim Zwischenspeichern des Webkontos ignoriert, wodurch Kontokonflikten im Cache verhindert werden.
Wenn Sie eine Unternehmens-App entwickeln, sollten Sie wahrscheinlich eine Verbindung mit einer Azure Active Directory (AAD)-Instanz herstellen und die Microsoft Graph-API anstelle regulärer MSA-Dienste verwenden. Verwenden Sie in diesem Szenario stattdessen den folgenden Code:
private async void GetAadTokenAsync(WebAccountProviderCommand command)
{
string clientId = "your_guid_here"; // Obtain your clientId from the Azure Portal
WebTokenRequest request = new WebTokenRequest(provider, "User.Read", clientId);
request.Properties.Add("resource", "https://graph.microsoft.com");
WebTokenRequestResult result = await WebAuthenticationCoreManager.RequestTokenAsync(request);
}
Der Rest dieses Artikels beschreibt weiterhin das MSA-Szenario, aber der Code für AAD ist sehr ähnlich. Weitere Informationen zu AAD/Graph, einschließlich eines vollständigen Beispiels auf GitHub, finden Sie in der Microsoft Graph-Dokumentation.
Verwenden des Tokens
Die RequestTokenAsync-Methode gibt ein WebTokenRequestResult -Objekt zurück, das die Ergebnisse Ihrer Anforderung enthält. Wenn Ihre Anforderung erfolgreich war, enthält sie ein Token.
private async void GetMsaTokenAsync(WebAccountProviderCommand command)
{
WebTokenRequest request = new WebTokenRequest(command.WebAccountProvider, "wl.basic");
WebTokenRequestResult result = await WebAuthenticationCoreManager.RequestTokenAsync(request);
if (result.ResponseStatus == WebTokenRequestStatus.Success)
{
string token = result.ResponseData[0].Token;
}
}
Hinweis
Wenn beim Anfordern eines Tokens eine Fehlermeldung angezeigt wird, stellen Sie sicher, dass Sie Ihre App dem Store zugeordnet haben, wie in Schritt 1 beschrieben. Ihre App kann kein Token abrufen, wenn Sie diesen Schritt übersprungen haben.
Sobald Sie über ein Token verfügen, können Sie es verwenden, um die API Ihres Anbieters aufzurufen. Im folgenden Code rufen wir die Benutzerinformationen der Microsoft Live-API auf, um grundlegende Informationen über den Benutzer abzurufen und in unserer Benutzeroberfläche anzuzeigen. Beachten Sie jedoch, dass in den meisten Fällen empfohlen wird, das Token einmal zu speichern und es dann in einer separaten Methode zu verwenden.
private async void GetMsaTokenAsync(WebAccountProviderCommand command)
{
WebTokenRequest request = new WebTokenRequest(command.WebAccountProvider, "wl.basic");
WebTokenRequestResult result = await WebAuthenticationCoreManager.RequestTokenAsync(request);
if (result.ResponseStatus == WebTokenRequestStatus.Success)
{
string token = result.ResponseData[0].Token;
var restApi = new Uri(@"https://apis.live.net/v5.0/me?access_token=" + token);
using (var client = new HttpClient())
{
var infoResult = await client.GetAsync(restApi);
string content = await infoResult.Content.ReadAsStringAsync();
var jsonObject = JsonObject.Parse(content);
string id = jsonObject["id"].GetString();
string name = jsonObject["name"].GetString();
UserIdTextBlock.Text = "Id: " + id;
UserNameTextBlock.Text = "Name: " + name;
}
}
}
Wie Sie verschiedene REST-APIs aufrufen, variiert zwischen Anbietern; Weitere Informationen zur Verwendung Ihres Tokens finden Sie in der API-Dokumentation des Anbieters.
Speichern des Kontos für die zukünftige Verwendung
Token sind nützlich, um sofort Informationen über einen Benutzer abzurufen, aber sie haben in der Regel unterschiedliche Lebensdauer – MSA-Token sind beispielsweise nur einige Stunden gültig. Glücklicherweise müssen Sie die AccountsSettingsPane nicht jedes Mal erneut anzeigen, wenn ein Token abläuft. Nachdem ein Benutzer Ihre App einmal autorisiert hat, können Sie die Kontoinformationen des Benutzers zur zukünftigen Verwendung speichern.
Verwenden Sie dazu die WebAccount-Klasse. Ein WebAccount wird von derselben Methode zurückgegeben, die Sie zum Anfordern des Tokens verwendet haben:
private async void GetMsaTokenAsync(WebAccountProviderCommand command)
{
WebTokenRequest request = new WebTokenRequest(command.WebAccountProvider, "wl.basic");
WebTokenRequestResult result = await WebAuthenticationCoreManager.RequestTokenAsync(request);
if (result.ResponseStatus == WebTokenRequestStatus.Success)
{
WebAccount account = result.ResponseData[0].WebAccount;
}
}
Sobald Sie über eine WebAccount-Instanz verfügen, können Sie sie ganz einfach speichern. Im folgenden Beispiel verwenden wir LocalSettings. Weitere Informationen zur Verwendung von LocalSettings und anderen Methoden zum Speichern von Benutzerdaten finden Sie unter Speichern und Abrufen von App-Einstellungen und -Daten.
private async void StoreWebAccount(WebAccount account)
{
ApplicationData.Current.LocalSettings.Values["CurrentUserProviderId"] = account.WebAccountProvider.Id;
ApplicationData.Current.LocalSettings.Values["CurrentUserId"] = account.Id;
}
Anschließend können wir eine asynchrone Methode wie die folgende verwenden, um zu versuchen, ein Token im Hintergrund mit dem gespeicherten WebAccount abzurufen.
private async Task<string> GetTokenSilentlyAsync()
{
string providerId = ApplicationData.Current.LocalSettings.Values["CurrentUserProviderId"]?.ToString();
string accountId = ApplicationData.Current.LocalSettings.Values["CurrentUserId"]?.ToString();
if (null == providerId || null == accountId)
{
return null;
}
WebAccountProvider provider = await WebAuthenticationCoreManager.FindAccountProviderAsync(providerId);
WebAccount account = await WebAuthenticationCoreManager.FindAccountAsync(provider, accountId);
WebTokenRequest request = new WebTokenRequest(provider, "wl.basic");
WebTokenRequestResult result = await WebAuthenticationCoreManager.GetTokenSilentlyAsync(request, account);
if (result.ResponseStatus == WebTokenRequestStatus.UserInteractionRequired)
{
// Unable to get a token silently - you'll need to show the UI
return null;
}
else if (result.ResponseStatus == WebTokenRequestStatus.Success)
{
// Success
return result.ResponseData[0].Token;
}
else
{
// Other error
return null;
}
}
Platzieren Sie die oben genannte Methode direkt vor dem Code, der den AccountsSettingsPane erstellt. Wenn das Token im Hintergrund abgerufen wird, muss der Bereich nicht angezeigt werden.
private void LoginButton_Click(object sender, RoutedEventArgs e)
{
string silentToken = await GetMsaTokenSilentlyAsync();
if (silentToken != null)
{
// the token was obtained. store a reference to it or do something with it here.
}
else
{
// the token could not be obtained silently. Show the AccountsSettingsPane
AccountsSettingsPane.Show();
}
}
Da das Abrufen eines Tokens im Hintergrund sehr einfach ist, sollten Sie dieses Verfahren verwenden, um Ihr Token zwischen Sitzungen zu aktualisieren, anstatt ein vorhandenes Token zwischenzuspeichern (da dieses Token jederzeit abläuft).
Hinweis
Im obigen Beispiel werden nur grundlegende Erfolgs- und Fehlerfälle behandelt. Ihre App sollte auch ungewöhnliche Szenarien berücksichtigen (z. B. ein Benutzer, der die Berechtigung Ihrer App widerruft oder sein Konto aus Windows entfernt), und sie ordnungsgemäß behandeln.
Entfernen eines gespeicherten Kontos
Wenn Sie ein Webkonto beibehalten, können Sie Ihren Benutzern die Möglichkeit geben, ihr Konto mit Ihrer App zu trennen. Auf diese Weise können sie sich effektiv von der App abmelden: Ihre Kontoinformationen werden beim Start nicht mehr automatisch geladen. Entfernen Sie dazu zunächst alle gespeicherten Konto- und Anbieterinformationen aus dem Speicher. Rufen Sie dann SignOutAsync auf, um den Cache zu löschen und vorhandene Token zu ungültig machen, die Ihre App möglicherweise hat.
private async Task SignOutAccountAsync(WebAccount account)
{
ApplicationData.Current.LocalSettings.Values.Remove("CurrentUserProviderId");
ApplicationData.Current.LocalSettings.Values.Remove("CurrentUserId");
account.SignOutAsync();
}
Hinzufügen von Anbietern, die WebAccountManager nicht unterstützen
Wenn Sie die Authentifizierung von einem Dienst in Ihre App integrieren möchten, dieser Dienst aber beispielsweise WebAccountManager - Google+ oder Twitter nicht unterstützt – können Sie diesen Anbieter weiterhin manuell zum AccountsSettingsPane hinzufügen. Erstellen Sie dazu ein neues WebAccountProvider-Objekt, geben Sie Ihren eigenen Namen und .png Symbol ein, und fügen Sie es dann der Liste "WebAccountProviderCommands" hinzu. Hier ist ein Stubcode:
private async void BuildPaneAsync(AccountsSettingsPane s, AccountsSettingsPaneCommandsRequestedEventArgs e)
{
// other code here
var twitterProvider = new WebAccountProvider("twitter", "Twitter", new Uri(@"ms-appx:///Assets/twitter-auth-icon.png"));
var twitterCmd = new WebAccountProviderCommand(twitterProvider, GetTwitterTokenAsync);
e.WebAccountProviderCommands.Add(twitterCmd);
// other code here
}
private async void GetTwitterTokenAsync(WebAccountProviderCommand command)
{
// Manually handle Twitter login here
}
Hinweis
Dadurch wird dem AccountsSettingsPane nur ein Symbol hinzugefügt und die Methode ausgeführt, die Sie angeben, wenn auf das Symbol geklickt wird (in diesem Fall GetTwitterTokenAsync). Sie müssen den Code angeben, der die tatsächliche Authentifizierung behandelt. Weitere Informationen finden Sie unter Webauthentifizierungsbroker, der Hilfsmethoden für die Authentifizierung mithilfe von REST-Diensten bereitstellt.
Hinzufügen einer benutzerdefinierten Kopfzeile
Sie können den Bereich "Kontoeinstellungen" mithilfe der HeaderText-Eigenschaft wie folgt anpassen:
private async void BuildPaneAsync(AccountsSettingsPane s, AccountsSettingsPaneCommandsRequestedEventArgs e)
{
// other code here
args.HeaderText = "MyAwesomeApp works best if you're signed in.";
// other code here
}
Überschreiben Sie den Kopfzeilentext nicht; halten Sie es kurz und süß. Wenn Ihr Anmeldevorgang kompliziert ist und Sie weitere Informationen anzeigen müssen, verknüpfen Sie den Benutzer mit einer separaten Seite mit einem benutzerdefinierten Link.
Hinzufügen von benutzerdefinierten Links
Sie können dem AccountsSettingsPane benutzerdefinierte Befehle hinzufügen, die als Links unter Den unterstützten WebAccountProviders angezeigt werden. Benutzerdefinierte Befehle eignen sich hervorragend für einfache Aufgaben im Zusammenhang mit Benutzerkonten, z. B. das Anzeigen einer Datenschutzrichtlinie oder das Starten einer Supportseite für Benutzer mit Problemen.
Ein Beispiel:
private async void BuildPaneAsync(AccountsSettingsPane s, AccountsSettingsPaneCommandsRequestedEventArgs e)
{
// other code here
var settingsCmd = new SettingsCommand(
"settings_privacy",
"Privacy policy",
async (x) => await Launcher.LaunchUriAsync(new Uri(@"https://privacy.microsoft.com/en-US/")));
e.Commands.Add(settingsCmd);
// other code here
}
Theoretisch können Sie Einstellungsbefehle für alles verwenden. Wir empfehlen jedoch, ihre Verwendung auf intuitive, kontobezogene Szenarien wie die oben beschriebenen zu beschränken.
Weitere Informationen
Windows.Security.Authentication.Web.Core-Namespace
Windows.Security.Credentials-Namespace