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 valorHomeAccountIdentifier
, 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
.
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.
Llamada a varias API con consentimiento incremental y 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.