Elección de un proveedor de autenticación de Microsoft Graph en función del escenario

Los proveedores de autenticación implementan el código necesario para adquirir un token mediante la Biblioteca de autenticación de Microsoft (MSAL), controlan algunos posibles errores en casos como consentimiento incremental, contraseñas expiradas y acceso condicional y, a continuación, establecen el encabezado de autorización de solicitud HTTP. En la tabla siguiente se enumeran los proveedores que coinciden con los escenarios de los distintos 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 en el nombre del usuario de forma segura. 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 AuthorizationCodeCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};

// https://learn.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, vea Plataforma de identidad de Microsoft y el flujo de credenciales de cliente de OAuth 2.0.

Con un certificado de cliente

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

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

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

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

var graphClient = new GraphServiceClient(clientCertCredential, scopes);

Uso de un secreto de cliente

// The client credentials flow requires that you request the
// /.default scope, and pre-configure 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" };

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

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

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

var graphClient = new GraphServiceClient(clientSecretCredential, 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 llama a Microsoft Graph API. Para obtener más información, lea Plataforma de identidad de Microsoft y flujo en nombre de OAuth 2.0

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 OnBehalfOfCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};

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

var onBehalfOfCredential = new OnBehalfOfCredential(
    tenantId, clientId, clientSecret, oboToken, options);

var graphClient = new GraphServiceClient(onBehalfOfCredential, scopes);

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 página única, 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 el inicio de sesión en dispositivos a través de 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 DeviceCodeCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
    ClientId = clientId,
    TenantId = tenantId,
    // Callback function that receives the user prompt
    // Prompt contains the generated device code that user must
    // enter during the auth process in the browser
    DeviceCodeCallback = (code, cancellation) =>
    {
        Console.WriteLine(code.Message);
        return Task.FromResult(0);
    },
};

// https://learn.microsoft.com/dotnet/api/azure.identity.devicecodecredential
var deviceCodeCredential = new DeviceCodeCredential(options);

var graphClient = new GraphServiceClient(deviceCodeCredential, scopes);

Proveedor de Windows integrado

El flujo de Windows integrado permite a los equipos Windows adquirir un token de acceso cuando se unen a un dominio de forma silenciosa. 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 tokens de acceso personalizado mediante MSAL.

Proveedor de tokens de acceso

public class IntegratedWindowsTokenProvider : IAccessTokenProvider
{
    private readonly IPublicClientApplication publicClient;

    /// <summary>
    /// Initializes a new instance of the <see cref="IntegratedWindowsTokenProvider"/> class.
    /// </summary>
    /// <param name="clientId">The client ID from the app registration in Azure.</param>
    /// <param name="tenantId">The tenant ID from the app registration in Azure.</param>
    public IntegratedWindowsTokenProvider(string clientId, string tenantId)
    {
        // From MSAL (Microsoft.Identity.Client)
        publicClient = PublicClientApplicationBuilder
            .Create(clientId)
            .WithTenantId(tenantId)
            .Build();

        AllowedHostsValidator = new AllowedHostsValidator();
    }

    /// <summary>
    /// Gets an <see cref="AllowedHostsValidator"/> that validates if the
    /// target host of a request is allowed for authentication.
    /// </summary>
    public AllowedHostsValidator AllowedHostsValidator { get; }

    /// <inheritdoc/>
    public async Task<string> GetAuthorizationTokenAsync(
        Uri uri,
        Dictionary<string, object>? additionalAuthenticationContext = null,
        CancellationToken cancellationToken = default)
    {
        var scopes = new[] { "User.Read" };
        var result = await publicClient
            .AcquireTokenByIntegratedWindowsAuth(scopes)
            .ExecuteAsync(cancellationToken);
        return result.AccessToken;
    }
}

Creación del cliente

// 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 authenticationProvider = new BaseBearerTokenAuthenticationProvider(
    new IntegratedWindowsTokenProvider(clientId, tenantId));

var graphClient = new GraphServiceClient(authenticationProvider);

return graphClient;

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://learn.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 que una aplicación inicie sesión en un usuario con su nombre de usuario y contraseña. Use este flujo solo cuando no pueda usar ningún otro flujo de OAuth. Para obtener más información, vea 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 UsernamePasswordCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};

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

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

var graphClient = new GraphServiceClient(userNamePasswordCredential, scopes);

Pasos siguientes