Share via


Llamada a una API web desde una aplicación móvil

Después de que la aplicación haya iniciado la sesión de un usuario y recibido los tokens, la Biblioteca de autenticación de Microsoft (MSAL) expone información sobre el usuario, el entorno del usuario y los tokens emitidos. La aplicación puede utilizar estos valores para llamar a una API web o mostrar un mensaje de bienvenida al usuario.

En este artículo, primero veremos el resultado de MSAL. Después, veremos cómo usar un token de acceso de AuthenticationResult o result para llamar a una API web protegida.

Resultado de MSAL

MSAL proporciona los valores siguientes:

  • AccessToken llama a API web protegidas en una solicitud de portador de HTTP.
  • IdToken contiene información útil sobre el usuario que ha iniciado sesión. Esta información incluye el nombre del usuario, el inquilino principal y un identificador único para el almacenamiento.
  • ExpiresOn es el tiempo de expiración del token. MSAL controla la actualización automática de una aplicación.
  • TenantId es el identificador del inquilino donde el usuario ha iniciado sesión. En el caso de los usuarios invitados en Microsoft Entra B2E, este valor identifica el inquilino donde el usuario ha iniciado sesión. El valor no identifica el inquilino principal del usuario.
  • Scopes indica los ámbitos que se han concedido con el token. Los ámbitos concedidos pueden ser un subconjunto de los ámbitos que ha solicitado.

MSAL también proporciona una abstracción para un valor Account. Un valor Account representa la cuenta de usuario con sesión iniciada actual:

  • HomeAccountIdentifier identifica el inquilino principal del usuario.
  • UserName es el nombre de usuario preferido del usuario. Este valor puede estar vacío para los usuarios de Azure AD B2C.
  • AccountIdentifier identifica al usuario que ha iniciado sesión. En la mayoría de los casos, este valor es el mismo que el valor HomeAccountIdentifier, a menos que el usuario sea un invitado de otro inquilino.

Llamar a una API

Una vez que tenga el token de acceso, podrá llamar a una API web. La aplicación usará el token para compilar una solicitud HTTP y después ejecutar la solicitud.

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 para iOS y macOS

Los métodos para adquirir tokens devuelven un objeto MSALResult. MSALResult expone una propiedad accessToken. Puede usar accessToken para llamar a una API web. Agregue esta propiedad al encabezado de autorización HTTP antes de llamar para acceder a la API web protegida.

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

Propiedades de AuthenticationResult en MSAL.NET

Los métodos para adquirir tokens devuelven AuthenticationResult. En el caso de los métodos asincrónicos, se devuelve Task<AuthenticationResult>.

En MSAL.NET, AuthenticationResult expone:

  • AccessToken para que la API web acceda a los recursos. Este parámetro es una cadena, normalmente un JWT con codificación en Base 64. El cliente nunca debe mirar dentro del token de acceso. No se garantiza que el formato permanezca estable y se pueda cifrar para el recurso. La escritura de código que depende del contenido de un token de acceso del cliente constituye una de las fuentes de errores y de interrupciones de la lógica de cliente más habituales. Para más información, consulte Tokens de acceso.
  • IdToken del usuario. Este parámetro es un JWT codificado. Para más información, consulte Tokens de id.
  • ExpiresOn indica el día y la hora a la que expira el token.
  • TenantId indica el inquilino en el que se encontró el usuario. Para usuarios invitados en escenarios Microsoft Entra B2B, el id. de inquilino es el inquilino invitado, no el inquilino único. Cuando se entrega el token para un usuario, AuthenticationResult también contiene información sobre dicho usuario. Para los flujos de cliente confidenciales en los que se solicitan tokens sin usuario para la aplicación, esta información de usuario está vacía.
  • Los Scopes para los que se emitió el token.
  • El identificador único del usuario.

IAccount

MSAL.NET define la noción de una cuenta mediante la interfaz IAccount. Este cambio importante proporciona la semántica correcta. El mismo usuario puede tener varias cuentas, en diferentes directorios de Microsoft Entra. También MSAL.NET proporciona mejor información en el caso de escenarios de invitado ya que se proporciona información de la cuenta doméstica. En el siguiente diagrama se muestra la estructura de la interfaz IAccount.

IAccount interface structure

La clase AccountId identifica una cuenta en un inquilino específico con las propiedades que se muestran en la tabla siguiente.

Propiedad Descripción
TenantId Representación de una cadena en un GUID, que es el identificador del inquilino donde reside la cuenta.
ObjectId Representación de una cadena en un GUID, que es el identificador del usuario a quien pertenece la cuenta en el inquilino.
Identifier Identificador único de la cuenta. Identifier es la concatenación de ObjectId y TenantId, separados por una coma. No están codificados en Base 64.

La interfaz IAccount representa información sobre una sola cuenta. El mismo usuario puede estar presente en distintos inquilinos, es decir, un usuario puede tener varias cuentas. Sus miembros se muestran en la siguiente tabla.

Propiedad Descripción
Username Una cadena que contiene el valor que se puede mostrar en formato UserPrincipalName (UPN), por ejemplo, john.doe@contoso.com. Esta cadena puede ser NULL, a diferencia de HomeAccountId y HomeAccountId.Identifier que no serán NULL. Esta propiedad reemplaza la propiedad DisplayableId de IUser en versiones anteriores de MSAL.NET.
Environment Una cadena que contiene el proveedor de identidades de esta cuenta, por ejemplo, login.microsoftonline.com. Esta propiedad reemplaza la propiedad IdentityProvider de IUser, salvo que IdentityProvider también tenía información sobre el inquilino además del entorno de nube. Aquí, el valor es solo el host.
HomeAccountId El identificador de la cuenta de inicio del usuario. Esta propiedad identifica unívocamente al usuario a través de los inquilinos de Microsoft Entra.

Uso del token para llamar a una API protegida

Después de que MSAL devuelva AuthenticationResult en result, agréguelo al encabezado de autorización HTTP antes de realizar la llamada para acceder a la API web protegida.

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

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

Realización de varias solicitudes de API

Para llamar varias veces a la misma API, o llamar a varias API, tenga en cuenta los asuntos siguientes al compilar la aplicación:

  • Consentimiento incremental: La Plataforma de identidad de Microsoft permite que las aplicaciones obtengan el consentimiento del usuario cuando se necesitan los permisos, en lugar de todos al principio. Cada vez que la aplicación está lista para llamar a una API, debe solicitar solo los ámbitos que necesita.

  • Acceso condicional: cuando realiza varias solicitudes de API, es posible que en determinados escenarios tenga que cumplir requisitos adicionales de acceso condicional. Los requisitos pueden aumentar de este modo si la primera solicitud no tiene ninguna directiva de acceso condicional y la aplicación intenta acceder en modo silencioso a una nueva API que requiere acceso condicional. Para controlar este problema, asegúrese de que detecta los errores de solicitudes silenciosas y prepárese para realizar una solicitud interactiva. Para obtener más información, consulte Guía de acceso condicional.

Para llamar a varias API con el mismo usuario, después de haber adquirido un token para el usuario, puede evitar solicitar repetidamente las credenciales del usuario llamando posteriormente a AcquireTokenSilent para obtener un token:

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

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

La interacción es necesaria en los siguientes casos:

  • El usuario ha dado su consentimiento para la primera API, pero ahora debe dar su consentimiento para más ámbitos. En este caso, se usa el consentimiento incremental.
  • La primera API no requiere autenticación multifactor, pero la siguiente API sí.
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();
}

Pasos siguientes

Avance al siguiente artículo de este escenario, Paso a producción.