Obtenir un jeton pour une application mobile qui appelle des API web
Pour pouvoir appeler des API web protégées, votre application doit disposer d'un jeton d'accès. Cet article décrit la procédure à suivre pour obtenir un jeton à l’aide de la bibliothèque d’authentification Microsoft (MSAL).
Définir une étendue
Lorsque vous demandez un jeton, définissez une étendue. L’étendue détermine les données auxquelles votre application peut accéder.
Pour définir une étendue, l'approche la plus simple consiste à combiner l'App ID URI
de l'API web souhaitée avec l'étendue .default
. Cette définition indique à la plateforme d’identités Microsoft que votre application a besoin de toutes les étendues définies sur le portail.
Android
String[] SCOPES = {"https://graph.microsoft.com/.default"};
iOS
let scopes = ["https://graph.microsoft.com/.default"]
Obtenir des jetons
Acquérir des jetons via MSAL
MSAL permet aux applications d’acquérir des jetons en mode silencieux et de manière interactive. Lorsque vous appelez AcquireTokenSilent()
ou AcquireTokenInteractive()
, MSAL renvoie un jeton d'accès pour les étendues demandées. La procédure appropriée consiste à effectuer une demande en mode silencieux, puis à revenir à une demande interactive.
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
Essayez d'abord d'acquérir un jeton de manière silencieuse :
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
}
Si MSAL renvoie MSALErrorInteractionRequired
, essayez d'acquérir des jetons de manière interactive :
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 pour iOS et macOS prend en charge différents modificateurs pour obtenir un jeton de manière interactive ou silencieuse :
- Paramètres courants pour l'obtention d'un jeton
- Paramètres permettant d'obtenir un jeton de manière interactive
- Paramètres permettant d'obtenir un jeton de manière silencieuse
Paramètres obligatoires dans MSAL.NET
AcquireTokenInteractive
n'a qu'un seul paramètre obligatoire : scopes
. Le paramètre scopes
énumère les chaînes qui définissent les étendues pour lesquelles un jeton est requis. Si le jeton est destiné à Microsoft Graph, vous trouvez les étendues nécessaires dans les informations de référence de chaque API Microsoft Graph. Dans les informations de référence, accédez à la section « Autorisations ».
Par exemple, pour répertorier les contacts de l'utilisateur, utilisez les étendues « User.Read », « Contacts.Read ». Pour plus d’informations, consultez la documentation de référence sur les autorisations Microsoft Graph.
Sur Android, vous pouvez spécifier l'activité parente lors de la création de l'application à l'aide de PublicClientApplicationBuilder
. Si vous ne spécifiez pas l'activité parente à ce moment-là, vous pouvez la spécifier ultérieurement à l'aide de .WithParentActivityOrWindow
, comme dans la section suivante. Si vous spécifiez l'activité parente, le jeton y revient après l'interaction. Si vous ne la spécifiez pas, l'appel .ExecuteAsync()
renvoie une exception.
Paramètres facultatifs particuliers dans MSAL.NET
Les sections suivantes décrivent les paramètres facultatifs de MSAL.NET.
WithPrompt
Le paramètre WithPrompt()
contrôle l'interactivité avec l'utilisateur en spécifiant une invite.
La classe définit les constantes suivantes :
SelectAccount
force le service d'émission de jeton de sécurité (STS) à présenter la boîte de dialogue de sélection de compte. La boîte de dialogue contient les comptes pour lesquels l'utilisateur dispose d'une session. Vous pouvez utiliser cette option pour permettre à l'utilisateur de choisir parmi différentes identités. Cette option oblige MSAL à envoyerprompt=select_account
au fournisseur d’identité.La constante
SelectAccount
est le paramètre par défaut. Elle fournit la meilleure expérience possible sur la base des informations disponibles. Les informations disponibles peuvent inclure le compte, la présence d'une session pour l'utilisateur, etc. Ne remplacez pas ce paramètre par défaut, sauf si vous avez une bonne raison de le faire.Consent
vous permet de demander à l'utilisateur de donner son consentement, même si celui-ci a déjà été accordé. Dans ce cas, MSAL envoieprompt=consent
au fournisseur d’identité.Vous souhaiterez peut-être utiliser la constante
Consent
dans les applications axées sur la sécurité pour lesquelles la gouvernance de l'organisation exige que les utilisateurs voient la boîte de dialogue de consentement chaque fois qu'ils utilisent l'application.ForceLogin
permet au service d'inviter l'utilisateur à entrer ses informations d'identification même si l'invite n'est pas nécessaire.Cette option peut être utile si l'acquisition du jeton échoue et que vous souhaitez permettre à l'utilisateur de se reconnecter. Dans ce cas, MSAL envoie
prompt=login
au fournisseur d’identité. Vous souhaiterez peut-être utiliser cette option dans les applications axées sur la sécurité pour lesquelles la gouvernance de l'organisation exige que l'utilisateur se connecte chaque fois qu'il accède à des parties spécifiques de l'application.Never
concerne uniquement .NET 4.5 et Windows Runtime (WinRT). Cette constante n'affichera aucune invite utilisateur, mais elle tentera d'utiliser le cookie stocké dans l'affichage web incorporé masqué. Pour plus d'informations, consultez Utilisation de navigateurs avec MSAL.NET.Si cette option échoue,
AcquireTokenInteractive
renvoie une exception pour vous informer qu'une interaction avec l'interface utilisateur est nécessaire. Utilisez ensuite un autre paramètrePrompt
.NoPrompt
n'envoie pas d'invite au fournisseur d'identité.Cette option n'est utile que pour les stratégies de modification de profil d'Azure Active Directory B2C. Pour plus d'informations, consultez Spécificités de B2C.
WithExtraScopeToConsent
Utilisez le modificateur WithExtraScopeToConsent
dans un scénario avancé où vous souhaitez que l'utilisateur fournisse son consentement préalable à plusieurs ressources. Vous pouvez utiliser ce modificateur lorsque vous ne souhaitez pas avoir recours au consentement incrémentiel, qui est normalement utilisé avec MSAL.NET ou la plateforme d’identités Microsoft. Pour plus d’informations, consultez Guide pratique pour obtenir le consentement préalable de l’utilisateur sur plusieurs ressources.
Exemple de code :
var result = await app.AcquireTokenInteractive(scopesForCustomerApi)
.WithExtraScopeToConsent(scopesForVendorApi)
.ExecuteAsync();
Autres paramètres facultatifs
Pour en savoir plus sur les autres paramètres facultatifs de AcquireTokenInteractive
, consultez la documentation de référence relative à AcquireTokenInteractiveParameterBuilder.
Acquérir des jetons via le protocole
Nous vous déconseillons d'utiliser directement le protocole pour obtenir des jetons. Si vous le faites, l'application ne prendra pas en charge certains scénarios impliquant l'authentification unique (SSO), la gestion des périphériques et l'accès conditionnel.
Lorsque vous utilisez le protocole pour obtenir des jetons destinés aux applications mobiles, effectuez deux demandes :
- Obtention d'un code d'autorisation
- Échange du code contre un jeton
Obtention d’un code d’autorisation
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
Obtention de l'accès et actualisation du jeton
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
Étapes suivantes
Découvrez plus d’informations en créant une application monopage (SPA) React qui connecte les utilisateurs dans cette série de tutoriels en plusieurs parties.
Explorer les exemples de code mobile de la plateforme d’identités Microsoft