Condividi tramite


Acquisire un token per un'app per dispositivi mobili che chiama le API Web

Prima che l'app possa chiamare API Web protette, è necessario un token di accesso. Questo articolo illustra il processo per ottenere un token usando Microsoft Authentication Library (MSAL).

Definire un ambito

Quando si richiede un token, definire un ambito. L'ambito determina quali dati risultano accessibili per l'app.

Il modo più semplice per definire un ambito consiste nel combinare il App ID URI desiderato dell'API Web con l'ambito .default. Questa definizione indica a Microsoft Identity Platform che l'app richiede tutti gli ambiti impostati nel portale.

Android

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

iOS

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

Acquisire i token

Acquisire i token tramite MSAL

MSAL permette alle app di acquisire i token in modo silenzioso e interattivo. Quando si chiama AcquireTokenSilent() o AcquireTokenInteractive(), MSAL restituisce un token di accesso per gli ambiti richiesti. Il modello corretto consiste nell'effettuare una richiesta invisibile all'utente e quindi eseguire il fallback a una richiesta interattiva.

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) {
            // One account found, attempt silent sign-in.
            sampleApp.acquireTokenSilentAsync(SCOPES, accounts.get(0), getAuthSilentCallback());
        } else if (accounts.isEmpty()) {
            // No accounts found. Interactively request a token.
            sampleApp.acquireToken(getActivity(), SCOPES, getAuthInteractiveCallback());
        } else {
            // Multiple accounts found. Handle according to your app logic.
            // You may need to prompt the user to select an 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

Provare prima di tutto ad acquisire un token in modo invisibile all'utente:


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
}

Se MSAL restituisce MSALErrorInteractionRequired, provare ad acquisire i token in modo interattivo:

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 per iOS e macOS supporta vari modificatori per ottenere un token in modo interattivo o silenzioso:

Parametri obbligatori in MSAL.NET

AcquireTokenInteractive ha un unico parametro obbligatorio: scopes. Il parametro scopes enumera le stringhe che definiscono gli ambiti per i quali è necessario un token. Se il token è per Microsoft Graph, gli ambiti necessari sono reperibili nelle informazioni di riferimento dell'API per ogni API Microsoft Graph. Nel riferimento passare alla sezione "Autorizzazioni".

Ad esempio, per elencare i contatti dell'utente, utilizzare l'ambito "User.Read", "Contacts.Read". Per altre informazioni, vedere le Informazioni di riferimento per le autorizzazioni dell'API Microsoft Graph.

In Android è possibile specificare l'attività padre quando si crea l'app usando PublicClientApplicationBuilder. Se non si specifica l'attività padre in quel momento, è possibile specificarla in un secondo momento usando .WithParentActivityOrWindow come illustrato nella sezione seguente. Se si specifica l'attività padre, il token torna all'attività padre dopo l'interazione. Se non viene specificato, la chiamata .ExecuteAsync() genera un'eccezione.

Parametri facoltativi specifici in MSAL.NET

Le sezioni seguenti illustrano i parametri facoltativi in MSAL.NET.

WithPrompt

Il parametro WithPrompt() viene usato per controllare l'interattività con l'utente specificando una richiesta.

Immagine che mostra i campi nella struttura Prompt. Questi valori costanti controllano l'interattività con l'utente definendo il tipo di richiesta visualizzato dal parametro WithPrompt().

La classe definisce le costanti seguenti:

  • SelectAccount forza il servizio token di sicurezza (STS) a presentare la finestra di dialogo di selezione dell'account. La finestra di dialogo contiene gli account per i quali l'utente dispone di una sessione. È possibile usare questa opzione quando si vuole consentire all'utente di scegliere tra identità diverse. Questa opzione consente a MSAL di inviare prompt=select_account al provider di identità.

    La costante SelectAccount è l'impostazione predefinita e offre la migliore esperienza possibile in base alle informazioni disponibili. Le informazioni disponibili possono includere account, la presenza di una sessione per l'utente e così via. Non modificarla se non si ha un buon motivo per farlo.

  • Consent consente di richiedere all'utente il consenso anche se il consenso è stato concesso in precedenza. In questo caso, MSAL invia prompt=consent al provider di identità.

    È possibile usare la costante Consent nelle applicazioni incentrate sulla sicurezza in cui la governance dell'organizzazione richiede agli utenti di visualizzare la finestra di dialogo di consenso ogni volta che usano l'applicazione.

  • ForceLogin consente al servizio di richiedere all'utente le credenziali anche se la richiesta non è necessaria.

    Questa opzione può essere utile se l'acquisizione del token non riesce e si vuole consentire all'utente di accedere di nuovo. In questo caso, MSAL invia prompt=login al provider di identità. Questa opzione viene usata con applicazioni incentrate sulla sicurezza in cui la governance dell'organizzazione richiede all'utente di eseguire di nuovo l'accesso ogni volta che si passa a parti specifiche di un'applicazione.

  • Never è solo per .NET 4.5 e Windows Runtime (WinRT). Questa costante non presenterà alcuna richiesta all'utente, ma tenterà di usare il cookie archiviato nella visualizzazione Web incorporata nascosta. Per altre informazioni, vedere Utilizzo dei Web browser con MSAL.NET.

    In tal caso, AcquireTokenInteractive genera un'eccezione per notificare che è necessaria un'interazione con l'interfaccia utente. Usare dunque un altro parametro Prompt.

  • NoPrompt non invia alcuna richiesta al provider di identità.

    Questa opzione è utile solo per i criteri di modifica del profilo di Azure Active Directory B2C. Per altre informazioni, vedere Specifiche di B2C.

WithExtraScopeToConsent

Usare il modificatore WithExtraScopeToConsent in uno scenario avanzato in cui si vuole che l'utente fornisca il consenso iniziale a diverse risorse. È possibile usare questo modificatore quando non si vuole usare il consenso incrementale, che viene in genere usato con MSAL.NET o Microsoft Identity Platform. Per altre informazioni, vedere Ricevere il consenso utente in anticipo per numerose risorse.

Ecco un esempio di codice:

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

Per altre informazioni su tutti gli altri parametri facoltativi per AcquireTokenInteractive, vedere la documentazione di riferimento per AcquireTokenInteractiveParameterBuilder.

Acquisire i token tramite il protocollo

Non è consigliabile usare direttamente il protocollo per ottenere i token. In questo caso, l'app non supporterà alcuni scenari che coinvolgono l'accesso Single Sign-On (SSO), la gestione dei dispositivi e l'Accesso condizionale.

Quando si usa il protocollo per ottenere i token per le app per dispositivi mobili, effettuare due richieste:

  • Ottenere un codice di autorizzazione.
  • Scambiare il codice per un token.

Ottenere un codice di autorizzazione

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

Ottenere l'accesso e aggiornare il 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

Passaggi successivi

  • Per ulteriori informazioni, creare un'applicazione a pagina singola (SPA) che effettua l'accesso degli utenti nella seguente serie di esercitazioni in più parti.

  • Esplorare gli esempi di codice per dispositivi mobili di Microsoft Identity Platform