Aplicación de demonio que llama a las API web: adquisición de un token

Después de que se ha construido una aplicación cliente confidencial, puede llamar a AcquireTokenForClient y pasar el ámbito y, opcionalmente, forzar una actualización del token para adquirir un token para la aplicación.

Solicitud de ámbitos

El ámbito que va a solicitar para un flujo de credenciales de cliente es el nombre del recurso seguido de /.default. Esta notación indica a Azure Active Directory (Azure AD) que use los permisos de nivel de aplicación declarados estáticamente durante el registro de la aplicación. Además, un administrador de inquilinos debe conceder estos permisos de API.

ResourceId = "someAppIDURI";
var scopes = new [] {  ResourceId+"/.default"};

Recursos de Azure AD (v1.0)

El ámbito usado para las credenciales del cliente siempre debe ser el identificador del recurso seguido de /.default.

Importante

Cuando MSAL solicita un token de acceso para un recurso que acepta tokens de acceso de la versión 1.0, Azure AD analiza la audiencia deseada del ámbito solicitado, para lo cual toma todo lo que hay delante de la última barra diagonal y lo usa como identificador del recurso. Por tanto si, al igual que Azure SQL Database (https://database.windows.net), el recurso espera una audiencia que finaliza con una barra diagonal (en el caso de Azure SQL Database, https://database.windows.net/), deberá solicitar un ámbito de https://database.windows.net//.default (tenga en cuenta la doble barra diagonal). Consulte también el problema de MSAL.NET 747: Resource url's trailing slash is omitted, which caused sql auth failure.

API AcquireTokenForClient

Para adquirir un token para la aplicación, usará AcquireTokenForClient o el equivalente, según la plataforma.

using Microsoft.Identity.Client;

// With client credentials flows, the scope is always of the shape "resource/.default" because the
// application permissions need to be set statically (in the portal or by PowerShell), and then granted by
// a tenant administrator.
string[] scopes = new string[] { "https://graph.microsoft.com/.default" };

AuthenticationResult result = null;
try
{
 result = await app.AcquireTokenForClient(scopes)
                  .ExecuteAsync();
}
catch (MsalUiRequiredException ex)
{
    // The application doesn't have sufficient permissions.
    // - Did you declare enough app permissions during app creation?
    // - Did the tenant admin grant permissions to the application?
}
catch (MsalServiceException ex) when (ex.Message.Contains("AADSTS70011"))
{
    // Invalid scope. The scope has to be in the form "https://resourceurl/.default"
    // Mitigation: Change the scope to be as expected.
}

AcquireTokenForClient usa la caché de tokens de aplicación.

En MSAL.NET, AcquireTokenForClient usa la caché de tokens de aplicación. (Todos los demás métodos AcquireTokenXX usan la caché de tokens de usuario). No llame a AcquireTokenSilent antes de llamar a AcquireTokenForClient, ya que AcquireTokenSilent usa la caché de tokens de usuario. AcquireTokenForClient comprueba la propia caché de tokens de aplicación y la actualiza.

Protocolo

Si no tiene todavía una biblioteca para el lenguaje elegido, es posible que quiera usar el protocolo directamente:

Primer caso: Acceso a la solicitud de token mediante un secreto compartido

POST /{tenant}/oauth2/v2.0/token HTTP/1.1           //Line breaks for clarity.
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=535fb089-9ff3-47b6-9bfb-4f1264799865
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret=qWgdYAmab0YSkuL1qKv5bPX
&grant_type=client_credentials

Segundo caso: Acceso a la solicitud de token mediante un certificado

POST /{tenant}/oauth2/v2.0/token HTTP/1.1               // Line breaks for clarity.
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_id=97e0a5b7-d745-40b6-94fe-5f77d35c6e05
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg
&grant_type=client_credentials

Para más información, consulte la documentación del protocolo: La Plataforma de identidad de Microsoft y el flujo de credenciales de cliente de OAuth 2.0

Solución de problemas

¿Ha usado el ámbito de recurso/.default?

Si recibe un mensaje de error que indica que ha usado un ámbito no válido, probablemente no ha usado el ámbito resource/.default.

Si se produce un error No tiene privilegios suficientes para completar la operación al llamar a la API, el administrador de inquilinos debe conceder permisos a la aplicación. Consulte el paso 6 del registro de la aplicación de cliente anterior. Normalmente verá un error similar al siguiente:

Failed to call the web API: Forbidden
Content: {
  "error": {
    "code": "Authorization_RequestDenied",
    "message": "Insufficient privileges to complete the operation.",
    "innerError": {
      "request-id": "<guid>",
      "date": "<date>"
    }
  }
}

¿Está llamando a su propia API?

Si la aplicación demonio llama a su propia API web y no pudo agregar un permiso de aplicación al registro de aplicaciones del demonio, debe agregar roles de aplicación al registro de aplicaciones de la API web.

Pasos siguientes

Avance al siguiente artículo de este escenario, Llamada a una API web.