Las aplicaciones de demonio usan permisos de aplicación en lugar de permisos delegados. Por lo tanto, el tipo de cuenta admitido no puede ser una cuenta en ningún directorio de la organización ni una cuenta de Microsoft personal (por ejemplo, Skype, Xbox, Outlook.com). No hay ningún administrador de inquilinos para otorgar consentimiento a una aplicación de demonio para una cuenta de Microsoft personal. Debe elegir Cuentas de mi organización o Cuentas de cualquier organización.
La autoridad especificada en la configuración de la aplicación debe tener inquilinos (con identificador o nombre de dominio asociado a la organización).
Incluso si quisiera proporcionar una herramienta para varios inquilinos, debería usar un id. de inquilino o un nombre de dominio y nocommon o organizations con este flujo, ya que el servicio no puede deducir de manera confiable qué inquilino debería usarse.
Configuración y creación de instancias de la aplicación
En las bibliotecas MSAL, las credenciales del cliente (secreto o certificado) se pasan como parámetro de la construcción de la aplicación cliente confidencial.
Importante
Aunque se trate de una aplicación de consola que se ejecuta como servicio, si es una aplicación de demonio debe ser una aplicación cliente confidencial.
Archivo de configuración
El archivo de configuración define:
La instancia de nube y el identificador de inquilino, que forman la autoridad.
El identificador de cliente que recibió del registro de la aplicación.
A continuación se muestra un ejemplo de definición de la configuración en un archivo appsettings.json. Este ejemplo se ha tomado del ejemplo de código del demonio de consola de .NET de GitHub.
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "[Enter here the tenantID or domain name for your Azure AD tenant]",
"ClientId": "[Enter here the ClientId for your application]",
"ClientCredentials": [
{
"SourceType": "ClientSecret",
"ClientSecret": "[Enter here a client secret for your application]"
}
]
}
}
# Credentials
TENANT_ID=Enter_the_Tenant_Info_Here
CLIENT_ID=Enter_the_Application_Id_Here
// You provide either a ClientSecret or a CertificateConfiguration, or a ClientAssertion. These settings are exclusive
CLIENT_SECRET=Enter_the_Client_Secret_Here
CERTIFICATE_THUMBPRINT=Enter_the_certificate_thumbprint_Here
CERTIFICATE_PRIVATE_KEY=Enter_the_certificate_private_key_Here
CLIENT_ASSERTION=Enter_the_Assertion_String_Here
# Endpoints
// the Azure AD endpoint is the authority endpoint for token issuance
AAD_ENDPOINT=Enter_the_Cloud_Instance_Id_Here // https://login.microsoftonline.com/
// the graph endpoint is the application ID URI of Microsoft Graph
GRAPH_ENDPOINT=Enter_the_Graph_Endpoint_Here // https://graph.microsoft.com/
Al crear un cliente confidencial con secretos de cliente, el archivo de configuración parameters.json en el ejemplo de demonio de Python es el siguiente:
{
"authority": "https://login.microsoftonline.com/<your_tenant_id>",
"client_id": "your_client_id",
"scope": [ "https://graph.microsoft.com/.default" ],
"secret": "The secret generated by Azure AD during your confidential app registration",
"endpoint": "https://graph.microsoft.com/v1.0/users"
}
Al crear un cliente confidencial con certificados, el archivo de configuración parameters.json en el ejemplo de demonio de Python es el siguiente:
{
"authority": "https://login.microsoftonline.com/<your_tenant_id>",
"client_id": "your_client_id",
"scope": [ "https://graph.microsoft.com/.default" ],
"thumbprint": "790E... The thumbprint generated by Azure AD when you upload your public cert",
"private_key_file": "server.pem",
"endpoint": "https://graph.microsoft.com/v1.0/users"
}
A continuación se muestra un ejemplo de definición de la configuración en un archivo appsettings.json. Este ejemplo se ha tomado del ejemplo de código del demonio de consola de .NET de GitHub.
{
"Instance": "https://login.microsoftonline.com/{0}",
"Tenant": "[Enter here the tenantID or domain name for your Azure AD tenant]",
"ClientId": "[Enter here the ClientId for your application]",
"ClientSecret": "[Enter here a client secret for your application]",
"CertificateName": "[Or instead of client secret: Enter here the name of a certificate (from the user cert store) as registered with your application]"
}
Proporcione ClientSecret o CertificateName. Estos valores son excluyentes.
Creación de una instancia de la aplicación MSAL
Para crear una instancia de la aplicación MSAL, agregue o importe el paquete MSAL (dependiendo del lenguaje), o haga referencia a él.
La construcción es diferente dependiendo de si usa secretos de cliente o certificados (o, como un escenario avanzado, aserciones firmadas).
Haga referencia al paquete
Haga referencia al paquete MSAL en el código de la aplicación.
Instale los paquetes ejecutando npm install en la carpeta donde resida el archivo package.json. A continuación, importe el paquete msal-node:
const msal = require('@azure/msal-node');
import msal
import json
import sys
import logging
Agregue el paquete NuGet Microsoft.Identity.Client a la aplicación y, a continuación, agregue una directiva using en el código para hacer referencia a él.
En MSAL.NET, la aplicación cliente confidencial está representada por la interfaz IConfidentialClientApplication.
using Microsoft.Identity.Client;
IConfidentialClientApplication app;
Creación de una instancia de aplicación cliente confidencial con un secreto de cliente
Este es el código para crear una instancia de aplicación cliente confidencial con un secreto de cliente:
class Program
{
static async Task Main(string[] _)
{
// Get the Token acquirer factory instance. By default it reads an appsettings.json
// file if it exists in the same folder as the app (make sure that the
// "Copy to Output Directory" property of the appsettings.json file is "Copy if newer").
TokenAcquirerFactory tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
// Configure the application options to be read from the configuration
// and add the services you need (Graph, token cache)
IServiceCollection services = tokenAcquirerFactory.Services;
services.AddMicrosoftGraph();
// By default, you get an in-memory token cache.
// For more token cache serialization options, see https://aka.ms/msal-net-token-cache-serialization
// Resolve the dependency injection.
var serviceProvider = tokenAcquirerFactory.Build();
// ...
}
}
# Pass the parameters.json file as an argument to this Python script. E.g.: python your_py_file.py parameters.json
config = json.load(open(sys.argv[1]))
# Create a preferably long-lived app instance that maintains a token cache.
app = msal.ConfidentialClientApplication(
config["client_id"], authority=config["authority"],
client_credential=config["secret"],
# token_cache=... # Default cache is in memory only.
# You can learn how to use SerializableTokenCache from
# https://msal-python.rtfd.io/en/latest/#msal.SerializableTokenCache
)
El elemento Authority es una concatenación de la instancia de nube y el identificador de inquilino, por ejemplo https://login.microsoftonline.com/contoso.onmicrosoft.com o https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee. En el archivo appsettings.json que se muestra en la sección Archivo de configuración, la instancia y el suscriptor se representan con los valores Instance y Tenant, respectivamente.
En el ejemplo de código del que se tomó el fragmento de código anterior, Authority es una propiedad de la clase AuthenticationConfig y se define como tal:
/// <summary>
/// URL of the authority
/// </summary>
public string Authority
{
get
{
return String.Format(CultureInfo.InvariantCulture, Instance, Tenant);
}
}
Creación de una instancia de aplicación cliente confidencial con un certificado de cliente
Este es el código para compilar una aplicación con un certificado:
El código en sí es exactamente el mismo. El certificado se describe en la configuración.
Hay muchas maneras de obtener el certificado. Para obtener más información, vea https://aka.ms/ms-id-web-certificates.
Este es el procedimiento para obtener el certificado de KeyVault. La identidad de Microsoft se delega en DefaultAzureCredential de Azure Identity y usó la identidad administrada cuando estuvo disponible para acceder al certificado desde KeyVault. Se puede depurar la aplicación localmente ya que, después, usará las credenciales de desarrollador.
# Pass the parameters.json file as an argument to this Python script. E.g.: python your_py_file.py parameters.json
config = json.load(open(sys.argv[1]))
# Create a preferably long-lived app instance that maintains a token cache.
app = msal.ConfidentialClientApplication(
config["client_id"], authority=config["authority"],
client_credential={"thumbprint": config["thumbprint"], "private_key": open(config['private_key_file']).read()},
# token_cache=... # Default cache is in memory only.
# You can learn how to use SerializableTokenCache from
# https://msal-python.rtfd.io/en/latest/#msal.SerializableTokenCache
)
Además de usar un secreto de cliente o un certificado, las aplicaciones cliente confidenciales también pueden demostrar su identidad mediante aserciones de cliente. Consulte CredentialDescription para obtener más información.
En MSAL Python, puede proporcionar notificaciones de cliente mediante las notificaciones que se firmarán con esta clave privada de ConfidentialClientApplication.
# Pass the parameters.json file as an argument to this Python script. E.g.: python your_py_file.py parameters.json
config = json.load(open(sys.argv[1]))
# Create a preferably long-lived app instance that maintains a token cache.
app = msal.ConfidentialClientApplication(
config["client_id"], authority=config["authority"],
client_credential={"thumbprint": config["thumbprint"], "private_key": open(config['private_key_file']).read()},
client_claims = {"client_ip": "x.x.x.x"}
# token_cache=... # Default cache is in memory only.
# You can learn how to use SerializableTokenCache from
# https://msal-python.rtfd.io/en/latest/#msal.SerializableTokenCache
)
En lugar de un secreto de cliente o un certificado, la aplicación cliente confidencial también puede demostrar su identidad mediante aserciones de cliente.
MSAL.NET tiene dos métodos para proporcionar aserciones firmadas a la aplicación cliente confidencial:
.WithClientAssertion()
.WithClientClaims()
Cuando use WithClientAssertion, proporcione un JWT firmado. Este escenario avanzado se detalla en las aserciones de cliente.
Cuando utilice WithClientClaims, MSAL.NET produce una aserción firmada que contiene las notificaciones esperadas por Microsoft Entra ID más las notificaciones de cliente adicionales que se quieren enviar.
Este código muestra cómo hacerlo: