Elegir un proveedor de autenticación de Microsoft Graph según el escenario

Los proveedores de autenticación implementan el código necesario para adquirir un token mediante la Biblioteca de autenticación de Microsoft (MSAL); controlar una serie de posibles errores para casos como consentimiento incremental, contraseñas expiradas y acceso condicional; y, a continuación, establezca el encabezado de autorización de la solicitud HTTP. En la tabla siguiente se muestra el conjunto de proveedores que coinciden con los escenarios de diferentes tipos de aplicación.

Escenario Flujo/concesión Público Proveedor
Aplicación de página única Código de autorización con PKCE Consumidor u organización delegados Proveedor de código de autorización
Aplicación web que llama a las API web
Código de autorización Consumidor u organización delegados Proveedor de código de autorización
Credenciales de cliente Solo aplicación Proveedor de credenciales de cliente
API web que llama a las API web
En nombre de Consumidor u organización delegados Proveedor en nombre de
Credenciales de cliente Solo aplicación Proveedor de credenciales de cliente
Aplicación de escritorio que llama a las API web
Interactive Consumidor u organización delegados Proveedor interactivo
Windows integrado Organización delegada Proveedor de Windows integrado
Propietario del recurso Organización delegada Proveedor de nombre de usuario y contraseña
Código de dispositivo Organización delegada Proveedor de código de dispositivo
Aplicación de demonio
Credenciales de cliente Solo aplicación Proveedor de credenciales de cliente
Aplicación móvil que llama a las API web
Interactive Consumidor u organización delegados Proveedor interactivo

Nota

Los siguientes fragmentos de código se escribieron con las versiones más recientes de sus respectivos SDK. Si encuentra errores del compilador con estos fragmentos de código, asegúrese de que tiene las versiones más recientes. Las siguientes bibliotecas de identidades de Azure proporcionan los proveedores de autenticación usados:

Proveedor de código de autorización

El flujo de código de autorización permite que las aplicaciones nativas y web obtengan tokens de forma segura en el nombre del usuario. Para más información, consulte Plataforma de identidad de Microsoft y flujo de código de autorización de OAuth 2.0.

var scopes = new[] { "User.Read" };

// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";

// Values from app registration
var clientId = "YOUR_CLIENT_ID";
var clientSecret = "YOUR_CLIENT_SECRET";

// For authorization code flow, the user signs into the Microsoft
// identity platform, and the browser is redirected back to your app
// with an authorization code in the query parameters
var authorizationCode = "AUTH_CODE_FROM_REDIRECT";

// using Azure.Identity;
var options = new TokenCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};

// https://docs.microsoft.com/dotnet/api/azure.identity.authorizationcodecredential
var authCodeCredential = new AuthorizationCodeCredential(
    tenantId, clientId, clientSecret, authorizationCode, options);

var graphClient = new GraphServiceClient(authCodeCredential, scopes);

Proveedor de credenciales de cliente

El flujo de credenciales de cliente permite que las aplicaciones de servicio se ejecuten sin interacción del usuario. El acceso se basa en la identidad de la aplicación. Para obtener más información, consulte Plataforma de identidad de Microsoft y el flujo de credenciales de cliente de OAuth 2.0.

Uso de un secreto de cliente

// The client credentials flow requires that you request the
// /.default scope, and preconfigure your permissions on the
// app registration in Azure. An administrator must grant consent
// to those permissions beforehand.
var scopes = new[] { "https://graph.microsoft.com/.default" };

// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";

// Values from app registration
var clientId = "YOUR_CLIENT_ID";
var clientSecret = "YOUR_CLIENT_SECRET";

// using Azure.Identity;
var options = new TokenCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};

// https://docs.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
var clientSecretCredential = new ClientSecretCredential(
    tenantId, clientId, clientSecret, options);

var graphClient = new GraphServiceClient(clientSecretCredential, scopes);

Con un certificado de cliente

var scopes = new[] { "https://graph.microsoft.com/.default" };

// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";

// Values from app registration
var clientId = "YOUR_CLIENT_ID";
var clientCertificate = new X509Certificate2("MyCertificate.pfx");

// using Azure.Identity;
var options = new TokenCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};

// https://docs.microsoft.com/dotnet/api/azure.identity.clientcertificatecredential
var clientCertCredential = new ClientCertificateCredential(
    tenantId, clientId, clientCertificate, options);

var graphClient = new GraphServiceClient(clientCertCredential, scopes);

Proveedor en nombre de

El flujo en nombre de se aplica cuando la aplicación llama a una API de servicio o web que, a su vez, llama al Graph API de Microsoft. Para obtener más información, lea Plataforma de identidad de Microsoft y flujo en nombre de OAuth 2.0

El Azure.Identity paquete no admite el flujo en nombre de a partir de la versión 1.4.0. En su lugar, cree un proveedor de autenticación personalizado mediante MSAL.

var scopes = new[] { "User.Read" };

// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";

// Values from app registration
var clientId = "YOUR_CLIENT_ID";
var clientSecret = "YOUR_CLIENT_SECRET";

// using Azure.Identity;
var options = new TokenCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};

// This is the incoming token to exchange using on-behalf-of flow
var oboToken = "JWT_TOKEN_TO_EXCHANGE";

var cca = ConfidentialClientApplicationBuilder
    .Create(clientId)
    .WithTenantId(tenantId)
    .WithClientSecret(clientSecret)
    .Build();

// DelegateAuthenticationProvider is a simple auth provider implementation
// that allows you to define an async function to retrieve a token
// Alternatively, you can create a class that implements IAuthenticationProvider
// for more complex scenarios
var authProvider = new DelegateAuthenticationProvider(async (request) => {
    // Use Microsoft.Identity.Client to retrieve token
    var assertion = new UserAssertion(oboToken);
    var result = await cca.AcquireTokenOnBehalfOf(scopes, assertion).ExecuteAsync();

    request.Headers.Authorization =
        new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result.AccessToken);
});

var graphClient = new GraphServiceClient(authProvider);

Proveedor implícito

No se recomienda el flujo de autenticación implícita debido a sus desventajas. Los clientes públicos, como las aplicaciones nativas y las aplicaciones de JavaScript, ahora deben usar el flujo de código de autorización con la extensión PKCE en su lugar. Referencia.

Proveedor de código de dispositivo

El flujo de código del dispositivo permite iniciar sesión en los dispositivos mediante otro dispositivo. Para obtener más información, consulte Plataforma de identidad de Microsoft y el flujo de código de dispositivo de OAuth 2.0.

var scopes = new[] { "User.Read" };

// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";

// Value from app registration
var clientId = "YOUR_CLIENT_ID";

// using Azure.Identity;
var options = new TokenCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};

// Callback function that receives the user prompt
// Prompt contains the generated device code that use must
// enter during the auth process in the browser
Func<DeviceCodeInfo, CancellationToken, Task> callback = (code, cancellation) => {
    Console.WriteLine(code.Message);
    return Task.FromResult(0);
};

// https://docs.microsoft.com/dotnet/api/azure.identity.devicecodecredential
var deviceCodeCredential = new DeviceCodeCredential(
    callback, tenantId, clientId, options);

var graphClient = new GraphServiceClient(deviceCodeCredential, scopes);

Proveedor de Windows integrado

El flujo de Windows integrado proporciona una manera para que los equipos Windows adquieran de forma silenciosa un token de acceso cuando están unidos a un dominio. Para obtener más información, consulte Autenticación de Windows integrados.

El Azure.Identity paquete no admite actualmente la autenticación integrada de Windows. En su lugar, cree un proveedor de autenticación personalizado mediante MSAL.

var scopes = new[] { "User.Read" };

// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";

// Value from app registration
var clientId = "YOUR_CLIENT_ID";

var pca = PublicClientApplicationBuilder
    .Create(clientId)
    .WithTenantId(tenantId)
    .Build();

// DelegateAuthenticationProvider is a simple auth provider implementation
// that allows you to define an async function to retrieve a token
// Alternatively, you can create a class that implements IAuthenticationProvider
// for more complex scenarios
var authProvider = new DelegateAuthenticationProvider(async (request) => {
    // Use Microsoft.Identity.Client to retrieve token
    var result = await pca.AcquireTokenByIntegratedWindowsAuth(scopes).ExecuteAsync();

    request.Headers.Authorization =
        new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result.AccessToken);
});

var graphClient = new GraphServiceClient(authProvider);

Proveedor interactivo

Las aplicaciones móviles (Xamarin y UWP) y las aplicaciones de escritorio usan el flujo interactivo para llamar a Microsoft Graph en nombre de un usuario. Para obtener más información, consulte Adquisición de tokens de forma interactiva.

var scopes = new[] { "User.Read" };

// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";

// Value from app registration
var clientId = "YOUR_CLIENT_ID";

// using Azure.Identity;
var options = new InteractiveBrowserCredentialOptions
{
    TenantId = tenantId,
    ClientId = clientId,
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
    // MUST be http://localhost or http://localhost:PORT
    // See https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/System-Browser-on-.Net-Core
    RedirectUri = new Uri("http://localhost"),
};

// https://docs.microsoft.com/dotnet/api/azure.identity.interactivebrowsercredential
var interactiveCredential = new InteractiveBrowserCredential(options);

var graphClient = new GraphServiceClient(interactiveCredential, scopes);

Proveedor de nombre de usuario y contraseña

El proveedor de nombre de usuario y contraseña permite a una aplicación iniciar sesión con un usuario mediante su nombre de usuario y contraseña. Use este flujo solo cuando no pueda usar ninguno de los demás flujos de OAuth. Para obtener más información, consulte Plataforma de identidad de Microsoft y la credencial de contraseña del propietario de recursos de OAuth 2.0.

var scopes = new[] { "User.Read" };

// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";

// Value from app registration
var clientId = "YOUR_CLIENT_ID";

// using Azure.Identity;
var options = new TokenCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};

var userName = "adelev@contoso.com";
var password = "P@ssword1!";

// https://docs.microsoft.com/dotnet/api/azure.identity.usernamepasswordcredential
var userNamePasswordCredential = new UsernamePasswordCredential(
    userName, password, tenantId, clientId, options);

var graphClient = new GraphServiceClient(userNamePasswordCredential, scopes);

Siguientes pasos