Hämta en token för en mobilapp som anropar webb-API:er

Innan appen kan anropa skyddade webb-API:er behöver den en åtkomsttoken. Den här artikeln beskriver hur du hämtar en token med hjälp av Microsoft Authentication Library (MSAL).

Definiera ett omfång

När du begär en token definierar du ett omfång. Omfånget avgör vilka data din app kan komma åt.

Det enklaste sättet att definiera ett omfång är att kombinera önskade webb-API:er App ID URI med omfånget .default. Den här definitionen anger för Microsofts identitetsplattform att din app kräver alla omfång som anges i portalen.

Android

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

iOS

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

Xamarin

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

Hämta token

Hämta token via MSAL

MED MSAL kan appar hämta token tyst och interaktivt. När du anropar AcquireTokenSilent() eller AcquireTokenInteractive()returnerar MSAL en åtkomsttoken för de begärda omfången. Det rätta mönstret är att göra en tyst begäran och sedan återgå till en interaktiv begäran.

Android

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());

iOS

Prova först att hämta en token tyst:


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
}

Om MSAL returnerar MSALErrorInteractionRequiredkan du försöka hämta token interaktivt:

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 och macOS stöder olika modifierare för att hämta en token interaktivt eller tyst:

Xamarin

I följande exempel visas den minimala koden för att hämta en token interaktivt. I exemplet används Microsoft Graph för att läsa användarens profil.

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();
}

Obligatoriska parametrar i MSAL.NET

AcquireTokenInteractive har bara en obligatorisk parameter: scopes. Parametern scopes räknar upp strängar som definierar de omfång som en token krävs för. Om token är för Microsoft Graph kan du hitta de nödvändiga omfången i API-referensen för varje Microsoft Graph-API. I referensen går du till avsnittet "Behörigheter".

Om du till exempel vill visa en lista över användarens kontakter använder du omfånget "User.Read", "Contacts.Read". Mer information finns i Behörighetsreferens för Microsoft Graph.

På Android kan du ange överordnad aktivitet när du skapar appen med hjälp PublicClientApplicationBuilderav . Om du inte anger den överordnade aktiviteten vid den tidpunkten kan du senare ange den med hjälp .WithParentActivityOrWindow av som i följande avsnitt. Om du anger överordnad aktivitet återgår token till den överordnade aktiviteten efter interaktionen. Om du inte anger det utlöser anropet .ExecuteAsync() ett undantag.

Specifika valfria parametrar i MSAL.NET

I följande avsnitt beskrivs de valfria parametrarna i MSAL.NET.

WithPrompt

Parametern WithPrompt() styr interaktiviteten med användaren genom att ange en uppmaning.

Image showing the fields in the Prompt structure. These constant values control interactivity with the user by defining the type of prompt displayed by the WithPrompt() parameter.

Klassen definierar följande konstanter:

  • SelectAccount tvingar säkerhetstokentjänsten (STS) att visa dialogrutan för kontoval. Dialogrutan innehåller de konton som användaren har en session för. Du kan använda det här alternativet när du vill låta användaren välja mellan olika identiteter. Det här alternativet kör MSAL att skicka prompt=select_account till identitetsprovidern.

    Konstanten SelectAccount är standard och ger effektivt bästa möjliga upplevelse baserat på tillgänglig information. Den tillgängliga informationen kan omfatta konto, närvaro av en session för användaren och så vidare. Ändra inte den här standardinställningen om du inte har en bra anledning att göra det.

  • Consent gör att du kan be användaren om medgivande även om medgivande har beviljats tidigare. I det här fallet skickar prompt=consent MSAL till identitetsprovidern.

    Du kanske vill använda konstanten Consent i säkerhetsfokuserade program där organisationsstyrningen kräver att användarna ser dialogrutan medgivande varje gång de använder programmet.

  • ForceLogin gör att tjänsten kan fråga användaren om autentiseringsuppgifter även om uppmaningen inte behövs.

    Det här alternativet kan vara användbart om tokenförvärvet misslyckas och du vill låta användaren logga in igen. I det här fallet skickar prompt=login MSAL till identitetsprovidern. Du kanske vill använda det här alternativet i säkerhetsfokuserade program där organisationsstyrningen kräver att användaren loggar in varje gång de får åtkomst till specifika delar av programmet.

  • Never är endast för .NET 4.5 och Windows Runtime (WinRT). Den här konstanten uppmanar inte användaren, men den försöker använda cookien som lagras i den dolda inbäddade webbvyn. Mer information finns i Använda webbläsare med MSAL.NET.

    Om det här alternativet misslyckas utlöser du AcquireTokenInteractive ett undantag för att meddela dig om att en interaktion med användargränssnittet behövs. Använd sedan en annan Prompt parameter.

  • NoPrompt skickar ingen uppmaning till identitetsprovidern.

    Det här alternativet är endast användbart för redigeringsprofilprinciper i Azure Active Directory B2C. Mer information finns i B2C-detaljer.

WithExtraScopeToConsent

WithExtraScopeToConsent Använd modifieraren i ett avancerat scenario där du vill att användaren ska ge förhandsmedgivande till flera resurser. Du kan använda den här modifieraren när du inte vill använda inkrementellt medgivande, som normalt används med MSAL.NET eller Microsofts identitetsplattform. Mer information finns i Ha användarens medgivande i förväg för flera resurser.

Här är ett kodexempel:

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

Mer information om de andra valfria parametrarna för AcquireTokenInteractivefinns i referensdokumentationen för AcquireTokenInteractiveParameterBuilder.

Hämta token via protokollet

Vi rekommenderar inte att du använder protokollet direkt för att hämta token. Om du gör det har appen inte stöd för vissa scenarier som omfattar enkel inloggning (SSO), enhetshantering och villkorsstyrd åtkomst.

När du använder protokollet för att hämta token för mobilappar gör du två begäranden:

  • Hämta en auktoriseringskod.
  • Byt ut koden mot en token.

Hämta en auktoriseringskod

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

Hämta åtkomst och uppdatera 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ästa steg

Gå vidare till nästa artikel i det här scenariot, Anropa ett webb-API.