Appeler une API web à partir d’une application mobile

Quand votre application connecte un utilisateur et reçoit des jetons, la Bibliothèque d’authentification Microsoft (MSAL) expose des informations sur l’utilisateur, l’environnement de l’utilisateur et les jetons émis. Votre application peut utiliser ces valeurs pour appeler une API web ou afficher un message de bienvenue à l’utilisateur.

Dans cet article, nous allons tout d’abord examiner le résultat de MSAL. Puis, nous verrons comment utiliser un jeton d’accès à partir de AuthenticationResult ou result pour appeler une API web protégée.

Résultat de MSAL

MSAL propose les valeurs suivantes :

  • AccessToken appelle des API web protégées dans une requête HTTP du porteur.
  • IdToken contient des informations utiles au sujet de l’utilisateur connecté. Ces informations incluent le nom de l’utilisateur, le locataire de base et un identificateur unique de stockage.
  • ExpiresOn détermine le délai d’expiration du jeton. MSAL gère l’actualisation automatique d’une application.
  • TenantId est l’identificateur du locataire où l’utilisateur est connecté. Pour les utilisateurs invités dans Microsoft Entra B2B, cette valeur identifie le locataire où l’utilisateur est connecté. La valeur n’identifie pas le locataire de base de l’utilisateur.
  • Scopes indique les étendues qui ont été accordées avec votre jeton. Les étendues accordées peuvent être un sous-ensemble des étendues demandées.

MSAL fournit également une abstraction d’une valeur Account. Une valeur Account représente le compte de connexion de l’utilisateur actuel :

  • HomeAccountIdentifier identifie le locataire de base de l’utilisateur.
  • UserName est le nom d’utilisateur par défaut de l’utilisateur. Cette valeur peut être vide pour les utilisateurs d’Azure AD B2C.
  • AccountIdentifier identifie l’utilisateur connecté. Dans la plupart des cas, cette valeur est identique à la valeur HomeAccountIdentifier, sauf si l’utilisateur est un invité dans un autre locataire.

Appeler une API

Une fois que vous disposez du jeton d’accès, vous pouvez appeler une API web. Votre application utilisera ensuite le jeton pour générer et exécuter une requête HTTP.

Android

        RequestQueue queue = Volley.newRequestQueue(this);
        JSONObject parameters = new JSONObject();

        try {
            parameters.put("key", "value");
        } catch (Exception e) {
            // Error when constructing.
        }
        JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, MSGRAPH_URL,
                parameters,new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                // Successfully called Graph. Process data and send to UI.
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                // Error.
            }
        }) {
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> headers = new HashMap<>();

                // Put access token in HTTP request.
                headers.put("Authorization", "Bearer " + authResult.getAccessToken());
                return headers;
            }
        };

        request.setRetryPolicy(new DefaultRetryPolicy(
                3000,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        queue.add(request);

MSAL pour iOS et macOS

Les méthodes d'acquisition de jetons renvoient un objet MSALResult. MSALResult expose une propriété accessToken. Vous pouvez utiliser accessToken pour appeler une API web. Ajoutez cette propriété à l’en-tête d’autorisation HTTP avant d’appeler l’API web protégée pour y accéder.

NSMutableURLRequest *urlRequest = [NSMutableURLRequest new];
urlRequest.URL = [NSURL URLWithString:"https://contoso.api.com"];
urlRequest.HTTPMethod = @"GET";
urlRequest.allHTTPHeaderFields = @{ @"Authorization" : [NSString stringWithFormat:@"Bearer %@", accessToken] };

NSURLSessionDataTask *task =
[[NSURLSession sharedSession] dataTaskWithRequest:urlRequest
     completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {}];
[task resume];
let urlRequest = NSMutableURLRequest()
urlRequest.url = URL(string: "https://contoso.api.com")!
urlRequest.httpMethod = "GET"
urlRequest.allHTTPHeaderFields = [ "Authorization" : "Bearer \(accessToken)" ]

let task = URLSession.shared.dataTask(with: urlRequest as URLRequest) { (data: Data?, response: URLResponse?, error: Error?) in }
task.resume()

Xamarin

Propriétés AuthenticationResult dans MSAL.NET

Les méthodes d'acquisition de jetons renvoient AuthenticationResult. Pour les méthodes asynchrones, Task<AuthenticationResult> retourne.

Dans MSAL.NET, AuthenticationResult expose :

  • AccessToken pour que l’API web accède aux ressources. Ce paramètre correspond à une chaîne, généralement un JWT encodé en base 64. Le client ne doit jamais regarder dans le jeton d’accès. La stabilité du format n’est pas garantie et ce dernier peut être chiffré pour la ressource. L’écriture de code qui dépend du contenu des jetons d’accès sur le client constitue l’une des sources d’erreurs et des ruptures de logique client les plus importantes. Pour plus d’informations, consultez Jetons d'accès.
  • IdToken pour l'utilisateur. Ce paramètre est un jeton JWT encodé. Pour plus d'informations, consultez Jetons d’ID.
  • ExpiresOn exprime la date et l'heure d’expiration du jeton.
  • TenantId contient le locataire dans lequel l’utilisateur a été trouvé. Pour les utilisateurs invités dans les scénarios Microsoft Entra B2B, l’ID de tenant est le tenant invité et non le tenant unique. Lorsque le jeton est remis pour un utilisateur, AuthenticationResult contient également les informations sur cet utilisateur. Pour les flux de clients confidentiels où les jetons sont demandés sans aucun utilisateur pour l’application, ces informations sur l’utilisateur sont manquantes ou inconnues.
  • Les Scopes pour lesquelles le jeton a été émis.
  • L’ID unique de l’utilisateur.

IAccount

MSAL.NET définit la notion de compte via l’interface IAccount. Ce changement cassant fournit la sémantique qui convient. Un même utilisateur peut disposer de plusieurs comptes, dans des répertoires Microsoft Entra différents. De plus, MSAL.NET fournit de meilleures informations dans les scénarios d’invité, car des informations de compte d’accueil sont fournies. Le schéma suivant présente la structure de l’interface IAccount.

IAccount interface structure

La classe AccountId identifie un compte dans un locataire spécifique avec les propriétés indiquées dans le tableau suivant.

Propriété Description
TenantId Une représentation de chaîne pour un identificateur global unique, qui correspond à l’ID du locataire où réside le compte.
ObjectId Une représentation de chaîne pour un identificateur global unique, qui correspond à l’ID de l’utilisateur qui possède le compte dans le locataire.
Identifier Identificateur unique pour ce compte. Identifier est la concaténation de ObjectId et de TenantId séparés par une virgule. Ils ne sont pas encodés base64.

L’interface IAccount représente les informations d’un seul compte. Le même utilisateur peut être présent dans différents locataires, ce qui signifie qu'un utilisateur peut disposer de plusieurs comptes. Ses membres sont disponibles dans le tableau suivant.

Propriété Description
Username Une chaîne contenant la valeur affichée au format UserPrincipalName (UPN), par exemple, john.doe@contoso.com. Cette chaîne peut être Null, alors que HomeAccountId et HomeAccountId.Identifier ne le sont pas. Cette propriété remplace la propriété DisplayableId de IUser dans les versions précédentes de MSAL.NET.
Environment Une chaine contenant le fournisseur d’identité de ce compte, par exemple, login.microsoftonline.com. Cette propriété remplace la propriété IdentityProvider de IUser, sauf que IdentityProvider disposait aussi des informations sur le locataire (en plus de l’environnement cloud). Ici, la valeur n’est que l’hôte.
HomeAccountId L'ID du compte d’accueil de l’utilisateur. Cette propriété identifie de façon unique l’utilisateur entre les tenants Microsoft Entra.

Utiliser le jeton pour appeler une API protégée

Après renvoi de AuthenticationResult par MSAL dans result, ajoutez-le à l’en-tête d’autorisation HTTP avant de passer l’appel pour accéder à l’API web protégée.

httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

// Call the web API.
HttpResponseMessage response = await _httpClient.GetAsync(apiUri);
...
}

Effectuer plusieurs requêtes vers l’API

Pour appeler la même API plusieurs fois ou appeler plusieurs API, prenez en compte les points suivants quand vous créez votre application :

  • Consentement incrémentiel : la plateforme d’identités Microsoft permet aux applications d’obtenir le consentement de l’utilisateur au moment où des autorisations sont requises, plutôt que d’obtenir toutes les autorisations au début. Chaque fois que votre application est prête à appeler une API, elle doit demander uniquement les étendues dont elle a besoin.

  • Accès conditionnel : Quand vous faites plusieurs demandes d’API, vous risquez de devoir répondre à des exigences d’accès conditionnel supplémentaires dans certains scénarios. Les exigences peuvent être plus nombreuses si la première requête n’a aucune stratégie d’accès conditionnel et que votre application tente d’accéder en mode silencieux à une nouvelle API qui requiert un accès conditionnel. Pour gérer ce problème, veillez à intercepter les erreurs des requêtes en mode silencieux et à vous préparer à effectuer une requête interactive. Pour plus d’informations, consultez l’aide relative à l’accès conditionnel.

Pour appeler plusieurs API pour le même utilisateur, après l’acquisition d’un jeton pour l’utilisateur, vous pouvez éviter de demander à l’utilisateur des informations d’identification à plusieurs reprises en appelant AcquireTokenSilent pour obtenir un jeton :

var result = await app.AcquireTokenXX("scopeApi1")
                      .ExecuteAsync();

result = await app.AcquireTokenSilent("scopeApi2")
                  .ExecuteAsync();

Une interaction est obligatoire quand :

  • L’utilisateur a donné son consentement pour la première API, mais doit également le donner pour d’autres d’étendues Dans ce cas, vous utilisez le consentement incrémentiel.
  • La première API ne nécessite aucune authentification multifacteur, contrairement à l’API qui suit.
var result = await app.AcquireTokenXX("scopeApi1")
                      .ExecuteAsync();

try
{
 result = await app.AcquireTokenSilent("scopeApi2")
                  .ExecuteAsync();
}
catch(MsalUiRequiredException ex)
{
 result = await app.AcquireTokenInteractive("scopeApi2")
                  .WithClaims(ex.Claims)
                  .ExecuteAsync();
}

Étapes suivantes

Passez à l’article suivant de ce scénario, Passer en production.