API web que llama a API web: Configuración del código
En este artículo se describe cómo configurar código para una aplicación de API web mediante el flujo de código de autorización de OAuth 2.0.
Microsoft recomienda usar el paquete NuGet Microsoft.Identity.Web al desarrollar API web de nivel inferior de llamada API protegidas por ASP.NET Core. Consulta API web protegida: Configuración de código | Microsoft.Identity.Web para ver una presentación rápida de la biblioteca en el contexto de una API web.
Requisitos previos
Configuración de la aplicación
Elige un idioma para la API web.
Secretos de cliente o certificados de cliente
Dado que la aplicación web ahora llama a una API web de nivel inferior, proporciona un secreto de cliente o un certificado de cliente en el archivo appsettings.json. También puedes agregar una sección que especifique:
- La dirección URL de la API web de nivel inferior.
- Los ámbitos necesarios para llamar a la API.
En el ejemplo siguiente, la sección GraphBeta
especifica esta configuración.
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "[Enter_the_Application_Id_Here]",
"TenantId": "common",
// To call an API
"ClientCredentials": [
{
"SourceType": "ClientSecret",
"ClientSecret":"[Enter_the_Client_Secret_Here]"
}
]
},
"GraphBeta": {
"BaseUrl": "https://graph.microsoft.com/beta",
"Scopes": ["user.read"]
}
}
Nota
Puedes proponer una colección de credenciales de cliente, incluida una solución sin credenciales, como la federación de identidades de carga de trabajo para Azure Kubernetes. Las versiones anteriores de Microsoft.Identity.Web expresaron el secreto de cliente en una sola propiedad "ClientSecret" en lugar de "ClientCredentials". Esto sigue siendo compatible con versiones anteriores, pero no puedes usar la propiedad "ClientSecret" y la colección "ClientCredentials".
En lugar de un secreto de cliente, puedes proporcionar un certificado de cliente. En el fragmento de código siguiente se muestra el uso de un certificado almacenado en Azure Key Vault.
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "[Enter_the_Application_Id_Here]",
"TenantId": "common",
// To call an API
"ClientCredentials": [
{
"SourceType": "KeyVault",
"KeyVaultUrl": "https://msidentitywebsamples.vault.azure.net",
"KeyVaultCertificateName": "MicrosoftIdentitySamplesCert"
}
]
},
"GraphBeta": {
"BaseUrl": "https://graph.microsoft.com/beta",
"Scopes": ["user.read"]
}
}
Advertencia
Si olvidas cambiar Scopes
a una matriz, cuando intentes usar IDownstreamApi
los ámbitos aparecerán como nulos, y IDownstreamApi
intentará una llamada anónima (sin autenticar) a la API descendente, lo cual resultará en un 401/unauthenticated
.
Microsoft.Identity.Web proporciona varias maneras de describir certificados, tanto mediante configuración como mediante código. Para obtener más información, consulta Microsoft.Identity.Web: uso de certificados en GitHub.
Program.cs
using Microsoft.Identity.Web;
// ...
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration, Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
// ...
Una aplicación web tiene que adquirir un token para la API de nivel inferior. Para especificarlo, agrega la línea .EnableTokenAcquisitionToCallDownstreamApi()
después de .AddMicrosoftIdentityWebApi(Configuration)
. Esta línea expone el servicio ITokenAcquisition
, que se puede usar en las acciones de controlador o páginas.
Sin embargo, un método alternativo es implementar una caché de tokens. Por ejemplo, agregar .AddInMemoryTokenCaches()
a Program.cs permite que el token se almacene en caché en memoria.
using Microsoft.Identity.Web;
// ...
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration, Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
// ...
Microsoft.Identity.Web proporciona dos mecanismos para llamar a una API web de nivel inferior desde otra API. La opción que elijas dependerá de si deseas llamar a Microsoft Graph o a otra API.
Opción 1: Llamada a Microsoft Graph
Para llamar a Microsoft Graph, Microsoft.Identity.Web te permite usar directamente GraphServiceClient
(expuesto por el SDK de Microsoft Graph) en las acciones de la API.
Nota
Hay un problema en curso para el SDK de Microsoft Graph v5+. Para obtener más información, consulta el problema de GitHub.
Para exponer Microsoft Graph:
- Agrega el paquete NuGet Microsoft.Identity.Web.GraphServiceClient al proyecto.
- Agrega
.AddMicrosoftGraph()
después de.EnableTokenAcquisitionToCallDownstreamApi()
en Program.cs..AddMicrosoftGraph()
tiene varias invalidaciones. Cuando se utiliza la invalidación que toma una sección de la configuración como parámetro, el código se convierte en:
using Microsoft.Identity.Web;
// ...
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration, Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph(Configuration.GetSection("GraphBeta"))
.AddInMemoryTokenCaches();
// ...
Opción 2: Llamada a una API web de nivel inferior que no sea Microsoft Graph
- Agrega el paquete NuGet Microsoft.Identity.Web.DownstreamApi al proyecto.
- Agregue
.AddDownstreamApi()
después de.EnableTokenAcquisitionToCallDownstreamApi()
en Program.cs. El código se convierte en:
using Microsoft.Identity.Web;
// ...
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDownstreamApi("MyApi", Configuration.GetSection("MyApiScope"))
.AddInMemoryTokenCaches();
// ...
donde:
MyApi
indica el nombre de la API web de bajada a la que pretende llamar la API web.MyApiScope
es el ámbito necesario para que la API web solicite para interactuar con la API web de bajada.
Estos valores se representarán en el JSON que será similar al fragmento de código siguiente.
"DownstreamAPI": {
"BaseUrl": "https://downstreamapi.contoso.com/",
"Scopes": "user.read"
},
Si la aplicación web necesita llamar a otro recurso de API, repita el método de la .AddDownstreamApi()
con el ámbito pertinente, como se muestra en el siguiente fragmento de código:
using Microsoft.Identity.Web;
// ...
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDownstreamApi("MyApi", Configuration.GetSection("MyApiScope"))
.AddDownstreamApi("MyApi2", Configuration.GetSection("MyApi2Scope"))
.AddInMemoryTokenCaches();
// ...
Tenga en cuenta que .EnableTokenAcquisitionToCallDownstreamApi
se llama sin ningún parámetro, lo que significa que el token de acceso se adquirirá justo a tiempo, ya que el controlador solicita el token especificando el ámbito.
El ámbito también se puede pasar al llamar a la .EnableTokenAcquisitionToCallDownstreamApi
, lo que haría que la aplicación web adquiriera el token durante el inicio de sesión del usuario. A continuación, el token se extraerá de la memoria caché cuando el controlador lo solicite.
De forma similar a las aplicaciones web, se pueden elegir varias implementaciones de caché de tokens. Para obtener más información, consulte Microsoft.Identity.Web: Serialización de la caché de tokens en GitHub.
En la imagen siguiente se muestran las posibilidades de Microsoft.Identity.Web y su impacto en Program.cs:
Nota:
Para comprender por completo los ejemplos de código que se indican a continuación, familiarízate con los aspectos básicos de ASP.NET Core y, en particular, con la inserción de dependencias y las opciones.
También puedes ver un ejemplo de implementación del flujo con derechos delegados en Node.js y Azure Functions.
Protocolo
Para obtener más información acerca del protocolo OBO, consulta Flujo con derechos delegados de OAuth 2.0 y Plataforma de identidad de Microsoft.