Ottenere 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 l'API App ID URI
Web desiderata 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"]
Xamarin
var scopes = new [] {"https://graph.microsoft.com/.default"};
Ottenere i token
Acquisire i token tramite MSAL
MSAL consente alle app di acquisire i token in modo invisibile all'utente e in modo 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) {
// 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
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 invisibile all'utente:
- Parametri comuni per ottenere un token
- Parametri per ottenere un token interattivo
- Parametri per ottenere un token invisibile all'utente
Xamarin
L'esempio seguente mostra il codice minimo per ottenere un token in modo interattivo. L'esempio usa Microsoft Graph per leggere il profilo dell'utente.
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();
}
Parametri obbligatori in MSAL.NET
AcquireTokenInteractive
ha un solo parametro obbligatorio: scopes
. Il scopes
parametro enumera le stringhe che definiscono gli ambiti per i quali è necessario un token. Se il token è per Microsoft Graph, è possibile trovare gli ambiti necessari nel riferimento API di ogni API Microsoft Graph. Nel riferimento passare alla sezione "Autorizzazioni".
Ad esempio, per elencare i contatti dell'utente, usare 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, in un secondo momento è possibile specificarla usando .WithParentActivityOrWindow
come nella sezione seguente. Se si specifica l'attività padre, il token torna all'attività padre dopo l'interazione. Se non viene specificato, la .ExecuteAsync()
chiamata genera un'eccezione.
Parametri facoltativi specifici in MSAL.NET
Le sezioni seguenti illustrano i parametri facoltativi in MSAL.NET.
WithPrompt
Il WithPrompt()
parametro controlla l'interattività con l'utente specificando un prompt.
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 inviareprompt=select_account
al provider di identità.La
SelectAccount
costante è l'impostazione predefinita e offre in modo efficace la migliore esperienza possibile in base alle informazioni disponibili. Le informazioni disponibili possono includere account, presenza di una sessione per l'utente e così via. Non modificare questa impostazione predefinita, a meno che non si abbia 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 inviaprompt=consent
al provider di identità.È possibile usare la
Consent
costante 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à. È possibile usare questa opzione nelle applicazioni incentrate sulla sicurezza in cui la governance dell'organizzazione richiede all'utente di accedere ogni volta che accedono a parti specifiche dell'applicazione.Never
è solo per .NET 4.5 e Windows Runtime (WinRT). Questa costante non richiederà all'utente, ma tenterà di usare il cookie archiviato nella visualizzazione Web incorporata nascosta. Per altre informazioni, vedere Uso di Web browser con MSAL.NET.Se questa opzione ha esito negativo,
AcquireTokenInteractive
genera un'eccezione per notificare che è necessaria un'interazione dell'interfaccia utente. Usare quindi un altroPrompt
parametro.NoPrompt
non invia una richiesta al provider di identità.Questa opzione è utile solo per i criteri del profilo di modifica in Azure Active Directory B2C. Per altre informazioni, vedere Specifiche di B2C.
WithExtraScopeToConsent
Usare il WithExtraScopeToConsent
modificatore 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 sugli 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
Passare all'articolo successivo in questo scenario, Chiamata di un'API Web.