Web-APIs aufrufende Desktop-App – Interaktiver Aufruf eines Tokens

Das folgende Beispiel enthält den mindestens erforderlichen Code zum interaktiven Abrufen eines Tokens zum Lesen des Benutzerprofils mit Microsoft Graph.

Code in MSAL.NET

string[] scopes = new string[] { "user.read" };

var app = PublicClientApplicationBuilder.Create("YOUR_CLIENT_ID")
    .WithDefaultRedirectUri()
    .Build();

var accounts = await app.GetAccountsAsync();

AuthenticationResult result;
try
{
    result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault())
      .ExecuteAsync();
}
catch (MsalUiRequiredException)
{
    result = await app.AcquireTokenInteractive(scopes).ExecuteAsync();
}

Erforderliche Parameter

AcquireTokenInteractive weist nur einen obligatorischen Parameter auf – scopes. Er enthält eine Enumeration von Zeichenfolgen, die die Bereiche definieren, für die ein Token erforderlich ist. Wenn das Token für Microsoft Graph gilt, können Sie die erforderlichen Bereiche in der API-Referenz der jeweiligen Microsoft Graph-API im Abschnitt „Berechtigungen“ finden. Um beispielsweise die Kontakte des Benutzers auflisten zu können, müssen Sie sowohl User.Read als auch Contacts.Read als Bereich verwenden. Weitere Informationen finden Sie in der Microsoft Graph-Referenz zu Berechtigungen.

Sowohl für Desktopanwendungen als auch für mobile Anwendungen ist es wichtig, das übergeordnete Element mithilfe von .WithParentActivityOrWindow anzugeben. In vielen Fällen ist dies eine Anforderung, und MSAL löst Ausnahmen aus.

Informationen zu Desktopanwendungen finden Sie unter Übergeordnete Fensterhandles.

Geben Sie für mobile Anwendungen Activity (Android) oder UIViewController (iOS) an.

Optionale Parameter in MSAL.NET

WithParentActivityOrWindow

Die Benutzeroberfläche ist wichtig, da sie interaktiv ist. AcquireTokenInteractive hat einen speziellen optionalen Parameter, der für die unterstützenden Plattformen die übergeordnete Benutzeroberfläche angeben kann. Wenn Sie .WithParentActivityOrWindow in einer Desktopanwendung verwenden, weist es je nach Plattform einen anderen Typ auf.

Alternativ können Sie beim Erstellen eines Fensters auf den optionalen Parameter für das übergeordnete Fenster verzichten, wenn Sie nicht steuern möchten, wo das Anmeldedialogfeld auf dem Bildschirm angezeigt wird. Diese Option gilt für Anwendungen, die auf einer Befehlszeile basieren, zum Übergeben von Aufrufen an einen anderen Backend-Dienst verwendet werden und keine Fenster für die Benutzerinteraktion benötigen.

// net45
WithParentActivityOrWindow(IntPtr windowPtr)
WithParentActivityOrWindow(IWin32Window window)

// Mac
WithParentActivityOrWindow(NSWindow window)

// .NET Standard (this will be on all platforms at runtime, but only on .NET Standard platforms at build time)
WithParentActivityOrWindow(object parent).

Anmerkungen:

  • In .NET Standard ist der erwartete object-Wert Activity für Android, UIViewController für iOS, NSWindow für Mac und IWin32Window oder IntPr für Windows.

  • Unter Windows müssen Sie AcquireTokenInteractive aus dem UI-Thread aufrufen, sodass der eingebettete Browser den entsprechenden UI-Synchronisierungskontext abruft. Erfolgt kein Aufruf aus dem Benutzeroberflächenthread, werden Meldungen möglicherweise nicht fehlerfrei übertragen, oder es treten Deadlock-Szenarien in der Benutzeroberfläche auf. Sie können die Microsoft-Authentifizierungsbibliothek (Microsoft Authentication Library, MSAL) aus dem Benutzeroberflächenthread aufrufen, wenn Sie sich nicht bereits im Benutzeroberflächenthread befinden, indem Sie Dispatcher in Windows Presentation Foundation (WPF) verwenden.

  • Wenn Sie mit WPF ein Fenster aus einem WPF-Steuerelement abrufen, können Sie die WindowInteropHelper.Handle-Klasse verwenden. Dann erfolgt der Aufruf aus einem WPF-Steuerelement (this):

    result = await app.AcquireTokenInteractive(scopes)
                      .WithParentActivityOrWindow(new WindowInteropHelper(this).Handle)
                      .ExecuteAsync();
    

WithPrompt

Sie verwenden WithPrompt(), um durch Angabe einer Eingabeaufforderung die Interaktivität mit dem Benutzer zu steuern. Sie können das genaue Verhalten mithilfe der Struktur Microsoft.Identity.Client.Prompt steuern.

Die Struktur definiert die folgenden Konstanten:

  • SelectAccount: Hiermit wird der Sicherheitstokendienst (Security Token Service, STS) gezwungen, das Dialogfeld zur Kontoauswahl mit Konten anzuzeigen, für die der Benutzer über eine Sitzung verfügt. Diese Option ist die Standardeinstellung. Diese Option ist nützlich, wenn Sie Benutzern die Auswahl unter verschiedenen Identitäten ermöglichen möchten.

    Diese Option bewirkt, dass MSAL prompt=select_account an den Identitätsanbieter sendet. Damit wird die bestmögliche Benutzererfahrung auf Grundlage der verfügbaren Informationen bereitgestellt (z. B. Konto und Vorhandensein einer Sitzung für den Benutzer). Ändern Sie diese Option nicht ohne einen triftigen Grund.

  • Consent: Hiermit können Sie erzwingen, dass der Benutzer zur Zustimmung aufgefordert wird, selbst wenn die Anwendung zuvor ihre Zustimmung erteilt hat. In diesem Fall sendet MSAL prompt=consent an den Identitätsanbieter. Sie können diese Option in bestimmten sicherheitsorientierten Anwendungen verwenden, wenn die Governance der Organisation vorschreibt, dass für den Benutzer bei jeder Verwendung der Anwendung das Zustimmungsdialogfeld angezeigt wird.

  • ForceLogin: Hiermit können Sie angeben, dass die Anwendung den Benutzer zur Eingabe von Anmeldeinformationen auffordert, selbst wenn eine solche Benutzerabfrage nicht erforderlich ist. Diese Option kann nützlich sein, um dem Benutzer das erneute Anmelden zu ermöglichen, wenn das Abrufen eines Tokens fehlschlägt. In diesem Fall sendet MSAL prompt=login an den Identitätsanbieter. Organisationen verwenden manchmal diese Option in sicherheitsorientierten Anwendungen, wenn die Governance vorschreibt, dass sich Benutzer beim Zugriff auf bestimmte Teile einer Anwendung jedes Mal anmelden müssen.

  • Create löst eine Anmeldeumgebung für externe Identitäten aus, indem prompt=create an den Identitätsanbieter gesendet wird. Diese Eingabeaufforderung sollte nicht für Azure Active Directory B2C(Azure AD B2C)-Apps gesendet werden. Weitere Informationen finden Sie unter Hinzufügen eines Benutzerflows für die Self-Service-Registrierung zu einer App.

  • Never(nur für .NET 4.5 und Windows-Runtime) fragt den Benutzer nicht ab. Es wird stattdessen versucht, das in der ausgeblendeten eingebetteten Webansicht gespeicherte Cookie zu verwenden.

    Die Verwendung dieser Option schlägt möglicherweise fehl. In diesem Fall löst AcquireTokenInteractive eine Ausnahme aus mit der Meldung, dass eine Interaktion auf der Benutzeroberfläche erforderlich ist. Verwenden Sie dann einen anderen Prompt-Parameter.

  • NoPrompt sendet keine Eingabeaufforderung an den Identitätsanbieter. Der Identitätsanbieter entscheidet, welche Anmeldeoberfläche für den Benutzer am besten geeignet ist (einmaliges Anmelden oder Kontoauswahl).

    Diese Option ist für die Bearbeitung von Profilrichtlinien in Azure AD B2C obligatorisch. Weitere Informationen finden Sie unter Spezifische Informationen zu Azure AD B2C.

WithUseEmbeddedWebView

Mit dieser Methode können Sie angeben, ob Sie die Verwendung einer eingebetteten Webansicht oder der Systemwebansicht (sofern verfügbar) erzwingen möchten. Weitere Informationen finden Sie unter Verwenden von Webbrowsern.

var result = await app.AcquireTokenInteractive(scopes)
                    .WithUseEmbeddedWebView(true)
                    .ExecuteAsync();

WithExtraScopeToConsent

Dieser Modifizierer wird in einem erweiterten Szenario verwendet, in dem der Benutzer vorab seine Zustimmung für verschiedene Ressourcen erteilen soll und nicht die schrittweise Zustimmung verwendet wird. Entwickler verwenden normalerweise die schrittweise Zustimmung mit MSAL.NET und der Microsoft Identity Platform. Weitere Informationen finden Sie unter Einholen der Benutzerzustimmung im Vorfeld für verschiedene Ressourcen.

var result = await app.AcquireTokenInteractive(scopesForCustomerApi)
                     .WithExtraScopeToConsent(scopesForVendorApi)
                     .ExecuteAsync();

WithCustomWebUi

Eine Webbenutzeroberfläche ist ein Mechanismus zum Aufrufen eines Browsers. Dieser Mechanismus kann ein dediziertes Benutzeroberflächen-Webbrowser-Steuerelement oder eine Möglichkeit sein, das Öffnen des Browsers zu delegieren. MSAL stellt zwar für die meisten Plattformen Implementierungen von Webbenutzeroberflächen bereit, dennoch möchten Sie in diesen Fällen den Browser möglicherweise selbst hosten:

  • Sie verfügen über Plattformen, die nicht explizit von MSAL abgedeckt werden, z. B. Blazor, Unity, Mono auf Desktops.
  • Sie möchten die Benutzeroberfläche Ihrer Anwendung testen und einen automatisierten Browser nutzen, der mit Selenium verwendet werden kann.
  • Der Browser und die App, die MSAL ausführen, befinden sich in separaten Prozessen.

Um dies zu erreichen, übergeben Sie eine start Url an MSAL, die in einem Browser angezeigt werden muss, damit der Benutzer Eingaben (z. B. seinen Benutzernamen) vornehmen kann. Nach Abschluss der Authentifizierung muss Ihre App die end Url, die einen von Microsoft Entra ID bereitgestellten Code enthält, an MSAL zurückgeben. Der Host der end Url ist immer der redirectUri. Zum Abfangen der end Url können Sie folgende Aktionen ausführen:

  • Überwachen von Browserumleitungen, bis die redirect Url erreicht wird.
  • Umleiten des Browsers zu einer URL, die Sie überwachen.

WithCustomWebUi ist ein Erweiterungspunkt, mit dem Sie Ihre eigene Benutzeroberfläche in öffentlichen Clientanwendungen bereitstellen können. Sie können auch angeben, dass Benutzer den /Authorize-Endpunkt des Identitätsanbieters durchlaufen, sich anmelden und zustimmen müssen. MSAL.NET kann dann den Authentifizierungscode einlösen und ein Token abrufen.

Sie können WithCustomWebUi beispielsweise in Visual Studio verwenden, damit Electron-Anwendungen (z. B. Visual Studio-Feedback) die Webinteraktion bereitstellen, während der Großteil der Arbeiten von MSAL.NET ausgeführt wird. Die Verwendung von WithCustomWebUi empfiehlt sich auch, wenn Sie UI-Automatisierung bereitstellen möchten.

In öffentlichen Clientanwendungen verwendet MSAL.NET den PKCE-Standard (Proof Key for Code Exchange), um die Einhaltung der Sicherheit zu gewährleisten. Der Code kann nur von MSAL.NET eingelöst werden. Weitere Informationen finden Sie unter RFC 7636 – Proof Key for Code Exchange by OAuth Public Clients.

using Microsoft.Identity.Client.Extensions;
Verwenden von WithCustomWebUi

Führen Sie folgende Schritte aus, um WithCustomWebUI zu verwenden:

  1. Implementieren Sie die ICustomWebUi-Schnittstelle. Weitere Informationen finden Sie auf dieser GitHub-Seite.

  2. Implementieren Sie eine AcquireAuthorizationCodeAsync-Methode, und übernehmen Sie die URL für den Autorisierungscode, den MSAL.NET berechnet.

  3. Lassen Sie den Benutzer die Interaktion mit dem Identitätsanbieter durchlaufen und die URL zurückgeben, über die der Identitätsanbieter Ihre Implementierung zusammen mit dem Autorisierungscode zurückgerufen hat. Bei auftretenden Problemen löst Ihre Implementierung eine MsalExtensionException-Ausnahme aus, um mit MSAL zusammenzuarbeiten.

  4. Verwenden Sie in Ihrem AcquireTokenInteractive-Aufruf den .WithCustomUI()-Modifizierer, indem die Instanz Ihrer benutzerdefinierten Webbenutzeroberfläche übergeben wird:

    result = await app.AcquireTokenInteractive(scopes)
                      .WithCustomWebUi(yourCustomWebUI)
                      .ExecuteAsync();
    

Das MSAL.NET-Team hat die Benutzeroberflächentests so umgeschrieben, dass Sie diesen Erweiterungsmechanismus verwenden können. Zeigen Sie bei Interesse die SeleniumWebUI-Klasse im MSAL.NET-Quellcode an.

Mehr Benutzerfreundlichkeit mit SystemWebViewOptions

Von MSAL.NET 4.1 SystemWebViewOptions können Sie Folgendes angeben:

  • Der URI, zu dem navigiert werden soll (BrowserRedirectError), oder das anzuzeigende HTML-Fragment (HtmlMessageError), wenn Anmelde- oder Zustimmungsfehler im Systemwebbrowser auftreten.
  • Der URI, zu dem navigiert werden soll (BrowserRedirectSuccess), oder das anzuzeigende HTML-Fragment (HtmlMessageSuccess), wenn die Anmeldung oder Zustimmung erfolgreich ist.
  • Aktion, die zum Starten des Systembrowsers ausgeführt werden soll. Sie können Ihre eigene Implementierung bereitstellen, indem Sie den OpenBrowserAsync-Delegaten festlegen. Die Klasse stellt außerdem eine Standardimplementierung für zwei Browser bereit: OpenWithEdgeBrowserAsync für Microsoft Edge und OpenWithChromeEdgeBrowserAsync für Microsoft Edge unter Chromium.

Zum Verwenden dieser Struktur können Sie etwas Ähnliches wie im folgenden Beispiel schreiben:

IPublicClientApplication app;
...

options = new SystemWebViewOptions
{
 HtmlMessageError = "<b>Sign-in failed. You can close this tab ...</b>",
 BrowserRedirectSuccess = "https://contoso.com/help-for-my-awesome-commandline-tool.html"
};

var result = app.AcquireTokenInteractive(scopes)
                .WithEmbeddedWebView(false)       // The default in .NET
                .WithSystemWebViewOptions(options)
                .Build();

Andere optionale Parameter

Weitere Informationen zu anderen optionalen Parametern für AcquireTokenInteractive finden Sie unter AcquireTokenInteractiveParameterBuilder.

Nächste Schritte

Fahren Sie mit dem nächsten Artikel in diesem Szenario fort: Aufrufen einer Web-API von der Desktop-App.