Abrufen eines Tokens für eine mobile App, die Web-APIs aufruftGet a token for a mobile app that calls web APIs

Damit Ihre App geschützte Web-APIs aufrufen kann, benötigt sie ein Zugriffstoken.Before your app can call protected web APIs, it needs an access token. In diesem Artikel werden Sie durch den Prozess zum Abrufen eines Tokens mit der Microsoft Authentication Library (MSAL) geführt.This article walks you through the process to get a token by using the Microsoft Authentication Library (MSAL).

Definieren eines BereichsDefine a scope

Wenn Sie ein Token anfordern, definieren Sie einen Bereich.When you request a token, define a scope. Der Gültigkeitsbereich bestimmt, auf welche Daten Ihre App zugreifen kann.The scope determines what data your app can access.

Die einfachste Vorgehensweise zum Definieren eines Bereichs besteht darin, den App ID URI der Web-API mit dem Bereich .default zu kombinieren.The easiest way to define a scope is to combine the desired web API's App ID URI with the scope .default. Diese Definition informiert Microsoft Identity Platform darüber, dass Ihre App alle im Portal festgelegten Bereiche benötigt.This definition tells the Microsoft identity platform that your app requires all scopes that are set in the portal.

AndroidAndroid

String[] SCOPES = {"https://graph.microsoft.com/.default"};

iOSiOS

let scopes = ["https://graph.microsoft.com/.default"]

XamarinXamarin

var scopes = new [] {"https://graph.microsoft.com/.default"};

Abrufen von TokenGet tokens

Abrufen von Token über MSALAcquire tokens via MSAL

Mit der MSAL können Apps Token stillschweigend und interaktiv abrufen.MSAL allows apps to acquire tokens silently and interactively. Wenn Sie AcquireTokenSilent() oder AcquireTokenInteractive() aufrufen, gibt MSAL ein Zugriffstoken für die angeforderten Bereiche zurück.When you call AcquireTokenSilent() or AcquireTokenInteractive(), MSAL returns an access token for the requested scopes. Die korrekte Vorgehensweise ist es, eine automatische Anforderung und anschließend eine interaktive Anforderung auszuführen.The correct pattern is to make a silent request and then fall back to an interactive request.

AndroidAndroid

String[] SCOPES = {"https://graph.microsoft.com/.default"};
PublicClientApplication sampleApp = new PublicClientApplication(
                    this.getApplicationContext(),
                    R.raw.auth_config);

// Check if there are any accounts we can sign in silently.
// Result is in the silent callback (success or error).
sampleApp.getAccounts(new PublicClientApplication.AccountsLoadedCallback() {
    @Override
    public void onAccountsLoaded(final List<IAccount> accounts) {

        if (accounts.isEmpty() && accounts.size() == 1) {
            // TODO: Create a silent callback to catch successful or failed request.
            sampleApp.acquireTokenSilentAsync(SCOPES, accounts.get(0), getAuthSilentCallback());
        } else {
            /* No accounts or > 1 account. */
        }
    }
});

[...]

// No accounts found. Interactively request a token.
// TODO: Create an interactive callback to catch successful or failed requests.
sampleApp.acquireToken(getActivity(), SCOPES, getAuthInteractiveCallback());

iOSiOS

Versuchen Sie zunächst, ein Token automatisch abzurufen:First try acquiring a token silently:


NSArray *scopes = @[@"https://graph.microsoft.com/.default"];
NSString *accountIdentifier = @"my.account.id";

MSALAccount *account = [application accountForIdentifier:accountIdentifier error:nil];

MSALSilentTokenParameters *silentParams = [[MSALSilentTokenParameters alloc] initWithScopes:scopes account:account];
[application acquireTokenSilentWithParameters:silentParams completionBlock:^(MSALResult *result, NSError *error) {

    if (!error)
    {
        // You'll want to get the account identifier to retrieve and reuse the account
        // for later acquireToken calls
        NSString *accountIdentifier = result.account.identifier;

        // Access token to call the web API
        NSString *accessToken = result.accessToken;
    }

    // Check the error
    if (error && [error.domain isEqual:MSALErrorDomain] && error.code == MSALErrorInteractionRequired)
    {
        // Interactive auth will be required, call acquireTokenWithParameters:error:
        return;
    }
}];

let scopes = ["https://graph.microsoft.com/.default"]
let accountIdentifier = "my.account.id"

guard let account = try? application.account(forIdentifier: accountIdentifier) else { return }
let silentParameters = MSALSilentTokenParameters(scopes: scopes, account: account)
application.acquireTokenSilent(with: silentParameters) { (result, error) in

    guard let authResult = result, error == nil else {

    let nsError = error! as NSError

    if (nsError.domain == MSALErrorDomain &&
        nsError.code == MSALError.interactionRequired.rawValue) {

            // Interactive auth will be required, call acquireToken()
            return
         }
         return
     }

    // You'll want to get the account identifier to retrieve and reuse the account
    // for later acquireToken calls
    let accountIdentifier = authResult.account.identifier

    // Access token to call the web API
    let accessToken = authResult.accessToken
}

Wenn MSAL MSALErrorInteractionRequired zurückgibt, versuchen Sie, Token interaktiv abzurufen:If MSAL returns MSALErrorInteractionRequired, then try acquiring tokens interactively:

UIViewController *viewController = ...; // Pass a reference to the view controller that should be used when getting a token interactively
MSALWebviewParameters *webParameters = [[MSALWebviewParameters alloc] initWithAuthPresentationViewController:viewController];
MSALInteractiveTokenParameters *interactiveParams = [[MSALInteractiveTokenParameters alloc] initWithScopes:scopes webviewParameters:webParameters];
[application acquireTokenWithParameters:interactiveParams completionBlock:^(MSALResult *result, NSError *error) {
    if (!error)
    {
        // You'll want to get the account identifier to retrieve and reuse the account
        // for later acquireToken calls
        NSString *accountIdentifier = result.account.identifier;

        NSString *accessToken = result.accessToken;
    }
}];
let viewController = ... // Pass a reference to the view controller that should be used when getting a token interactively
let webviewParameters = MSALWebviewParameters(authPresentationViewController: viewController)
let interactiveParameters = MSALInteractiveTokenParameters(scopes: scopes, webviewParameters: webviewParameters)
application.acquireToken(with: interactiveParameters, completionBlock: { (result, error) in

    guard let authResult = result, error == nil else {
        print(error!.localizedDescription)
        return
    }

    // Get access token from result
    let accessToken = authResult.accessToken
})

MSAL für iOS und macOS unterstützt verschiedene Modifizierer, um Token interaktiv oder automatisch abzurufen:MSAL for iOS and macOS supports various modifiers to get a token interactively or silently:

XamarinXamarin

Das folgende Beispiel zeigt den minimal erforderlichen Code zum interaktiven Abrufen eines Codes.The following example shows the minimal code to get a token interactively. Das Beispiel verwendet Microsoft Graph zum Lesen des Profils des Benutzers.The example uses Microsoft Graph to read the user's profile.

string[] scopes = new string[] {"user.read"};
var app = PublicClientApplicationBuilder.Create(clientId).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 in MSAL.NETMandatory parameters in MSAL.NET

AcquireTokenInteractive weist nur einen obligatorischen Parameter auf: scopes.AcquireTokenInteractive has only one mandatory parameter: scopes. Der scopes-Parameter enumeriert Zeichenfolgen , die die Bereiche definieren, für die ein Token erforderlich ist.The scopes parameter enumerates strings that define the scopes for which a token is required. Wenn das Token für Microsoft Graph bestimmt ist, finden Sie die erforderlichen Bereiche in der API-Referenz der einzelnen Microsoft Graph-APIs.If the token is for Microsoft Graph, you can find the required scopes in the API reference of each Microsoft Graph API. Navigieren Sie in der Referenz zum Abschnitt „Berechtigungen“.In the reference, go to the "Permissions" section.

Um beispielsweise die Kontakte des Benutzers aufzulisten, verwenden Sie den Bereich „User.Read“, „Contacts.Read“.For example, to list the user's contacts, use the scope "User.Read", "Contacts.Read". Weitere Informationen finden Sie in der Microsoft Graph-Referenz zu Berechtigungen.For more information, see Microsoft Graph permissions reference.

Unter Android können Sie beim Erstellen der App mithilfe von PublicClientApplicationBuilder eine übergeordnete Aktivität angeben.On Android, you can specify parent activity when you create the app by using PublicClientApplicationBuilder. Wenn Sie die übergeordnete Aktivität nicht zu diesem Zeitpunkt festlegen, können Sie sie später mithilfe von .WithParentActivityOrWindow angeben, wie im folgenden Abschnitt zu sehen.If you don't specify the parent activity at that time, later you can specify it by using .WithParentActivityOrWindow as in the following section. Wenn Sie die übergeordnete Aktivität angeben, wird das Token nach der Interaktion wieder an diese übergeordnete Aktivität übergeben.If you specify parent activity, then the token gets back to that parent activity after the interaction. Wenn Sie sie nicht angeben, wird durch den .ExecuteAsync()-Aufruf eine Ausnahme ausgelöst.If you don't specify it, then the .ExecuteAsync() call throws an exception.

Spezifische optionale Parameter in MSAL.NETSpecific optional parameters in MSAL.NET

In den folgenden Abschnitten werden die optionalen Parameter in MSAL.NET erläutert.The following sections explain the optional parameters in MSAL.NET.

WithPromptWithPrompt

Der WithPrompt()-Parameter steuert die Interaktivität mit dem Benutzer durch Angabe einer Eingabeaufforderung.The WithPrompt() parameter controls interactivity with the user by specifying a prompt.

Abbildung mit den Feldern in der Struktur der Eingabeaufforderung

Die Klasse definiert die folgenden Konstanten:The class defines the following constants:

  • SelectAccount zwingt den Sicherheitstokendienst (Security Token Service, STS), das Dialogfeld zur Kontoauswahl darzustellen.SelectAccount forces the security token service (STS) to present the account-selection dialog box. Das Dialogfeld enthält die Konten, für die der Benutzer über eine Sitzung verfügt.The dialog box contains the accounts for which the user has a session. Sie können diese Option verwenden, wenn Sie dem Benutzer die Wahl zwischen verschiedenen Identitäten geben möchten.You can use this option when you want to let the user choose among different identities. Diese Option bewirkt, dass MSAL prompt=select_account an den Identitätsanbieter sendet.This option drives MSAL to send prompt=select_account to the identity provider.

    Die Konstante SelectAccount stellt den Standardwert dar, und sie bietet in der Praxis die bestmögliche Benutzererfahrung auf der Grundlage der vorhandenen Informationen.The SelectAccount constant is the default, and it effectively provides the best possible experience based on the available information. Zu den verfügbaren Informationen können etwa das Konto, das Vorhandensein einer Sitzung für den Benutzer usw. zählen.The available information might include account, presence of a session for the user, and so on. Ändern Sie diesen Standardwert nicht ohne triftigen Grund.Don't change this default unless you have a good reason to do it.

  • Consent ermöglicht es Ihnen, die Zustimmung des Benutzers anzufordern, auch wenn die Zustimmung bereits erteilt wurde.Consent enables you to prompt the user for consent even if consent was granted before. In diesem Fall sendet MSAL prompt=consent an den Identitätsanbieter.In this case, MSAL sends prompt=consent to the identity provider.

    Es kann sinnvoll sein, die Consent-Konstante in Anwendungen mit einem starken Schwerpunkt auf der Sicherheit zu verwenden, wenn die Governance der Organisation es erfordert, den Benutzern bei jedem Verwenden der Anwendung ein Zustimmungsdialogfeld anzuzeigen.You might want to use the Consent constant in security-focused applications where the organization governance requires users to see the consent dialog box each time they use the application.

  • ForceLogin ermöglicht es dem Dienst, den Benutzer zur Eingabe von Anmeldeinformationen aufzufordern, auch wenn keine Eingabeaufforderung erforderlich ist.ForceLogin enables the service to prompt the user for credentials even if the prompt isn't needed.

    Diese Option kann nützlich sein, wenn beim Tokenerwerb ein Fehler auftritt, und Sie dem Benutzer die erneute Anmeldung ermöglichen wollen.This option can be useful if the token acquisition fails and you want to let the user sign in again. In diesem Fall sendet MSAL prompt=login an den Identitätsanbieter.In this case, MSAL sends prompt=login to the identity provider. Die Verwendung dieser Option kann in sicherheitsorientierten Anwendungen sinnvoll sein, wenn die Governance der Organisation vorschreibt, dass sich Benutzer beim Zugriff auf bestimmte Teile einer Anwendung stets erneut anmelden müssen.You might want to use this option in security-focused applications where the organization governance requires the user to sign in each time they access specific parts of the application.

  • Never ist nur für .NET 4.5 und Windows Runtime (WinRT) verfügbar.Never is for only .NET 4.5 and Windows Runtime (WinRT). Mit dieser Konstante ergeht keine Aufforderung an den Benutzer, vielmehr wird versucht, das in der verborgenen eingebetteten Webansicht gespeicherte Cookie zu verwenden.This constant won't prompt the user, but it will try to use the cookie that's stored in the hidden embedded web view. Weitere Informationen finden Sie unter Verwenden von Webbrowsern mit MSAL.NET.For more information, see Using web browsers with MSAL.NET.

    Wenn bei dieser Option ein Fehler auftritt, löst AcquireTokenInteractive eine Ausnahme aus, um Sie zu informieren, dass ein Eingriff an der Benutzeroberfläche erforderlich ist.If this option fails, then AcquireTokenInteractive throws an exception to notify you that a UI interaction is needed. Verwenden Sie dann einen anderen Prompt-Parameter.Then use another Prompt parameter.

  • NoPrompt sendet keine Eingabeaufforderung an den Identitätsanbieter.NoPrompt doesn't send a prompt to the identity provider.

    Diese Option ist nur für Richtlinien für die Profilbearbeitung in Azure Active Directory B2C nützlich.This option is useful only for edit-profile policies in Azure Active Directory B2C. Weitere Informationen finden Sie unter Spezifische Informationen zu B2C.For more information, see B2C specifics.

WithExtraScopeToConsentWithExtraScopeToConsent

Verwenden Sie den WithExtraScopeToConsent-Modifizierer in einem erweiterten Szenario, in dem Sie möchten, dass der Benutzer vorab seine Zustimmung zu mehreren Ressourcen erteilt.Use the WithExtraScopeToConsent modifier in an advanced scenario where you want the user to provide upfront consent to several resources. Sie können diesen Modifizierer verwenden, wenn Sie keine inkrementelle Zustimmung verwenden möchten, die normalerweise mit MSAL.NET oder Microsoft Identity Platform verwendet wird.You can use this modifier when you don't want to use incremental consent, which is normally used with MSAL.NET or the Microsoft identity platform. Weitere Informationen finden Sie unter Einholen der Vorauseinwilligung des Benutzers für verschiedene Ressourcen.For more information, see Have the user consent upfront for several resources.

Hier sehen Sie ein Codebeispiel:Here's a code example:

var result = await app.AcquireTokenInteractive(scopesForCustomerApi)
                     .WithExtraScopeToConsent(scopesForVendorApi)
                     .ExecuteAsync();
Andere optionale ParameterOther optional parameters

Informationen zu den anderen optionalen Parametern für AcquireTokenInteractive finden Sie in der Referenzdokumentation für AcquireTokenInteractiveParameterBuilder.To learn about the other optional parameters for AcquireTokenInteractive, see the reference documentation for AcquireTokenInteractiveParameterBuilder.

Abrufen von Token über das ProtokollAcquire tokens via the protocol

Die direkte Verwendung des Protokolls zum Abrufen von Token wird nicht empfohlen.We don't recommend directly using the protocol to get tokens. Wenn Sie dies tun, werden einige Szenarien, die einmaliges Anmelden (Single Sign-On, SSO), die Geräteverwaltung und den bedingten Zugriff beinhalten, von der App nicht unterstützt.If you do, then the app won't support some scenarios that involve single sign-on (SSO), device management, and conditional access.

Wenn Sie das Protokoll verwenden, um Token für mobile Apps abzurufen, machen Sie zwei Anforderungen:When you use the protocol to get tokens for mobile apps, make two requests:

  • Abrufen eine AutorisierungscodesGet an authorization code.
  • Austausch des Codes gegen ein TokenExchange the code for a token.

Abrufen von AutorisierungscodesGet an authorization code

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=<CLIENT_ID>
&response_type=code
&redirect_uri=<ENCODED_REDIRECT_URI>
&response_mode=query
&scope=openid%20offline_access%20https%3A%2F%2Fgraph.microsoft.com%2F.default
&state=12345

Erhalten des Zugriffs und Aktualisieren des TokensGet access and refresh the token

POST /{tenant}/oauth2/v2.0/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=<CLIENT_ID>
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr...
&redirect_uri=<ENCODED_REDIRECT_URI>
&grant_type=authorization_code

Nächste SchritteNext steps

Fahren Sie mit dem nächsten Artikel in diesem Szenario fort: Aufrufen einer Web-API.Move on to the next article in this scenario, Calling a web API.