Se aplica a:
Inquilinos de la fuerza laboral (más información)
Aprende a configurar el código de la aplicación daemon que llama a las API web.
Bibliotecas de Microsoft que admiten aplicaciones de demonio
Las siguientes bibliotecas de Microsoft admiten aplicaciones daemon:
1Los términos de licencia universales para Servicios en línea se aplican a las bibliotecas en versión preliminar pública.
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 un administrador del inquilino que pueda conceder el consentimiento a una aplicación daemon para una cuenta personal de Microsoft. 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 incluir el identificador de inquilino o un 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.
En las Bibliotecas de autenticación de Microsoft (MSAL), las credenciales del cliente (secreto o certificado) se proporcionan como parámetro al crear la aplicación cliente confidencial.
Importante
Aunque la aplicación sea una aplicación de consola que se ejecuta como servicio, si es una aplicación daemon, 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 id. de cliente que obtuvo al registrar la aplicación.
- Un secreto de cliente o un certificado.
Este es un ejemplo de definición de la configuración en un archivo de configuración deappsettings.json ejemplo. 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]"
}
]
}
}
Debe proporcionar un certificado en lugar del secreto de cliente o las credenciales de federación de identidad de carga de trabajo.
En el ejemplo siguiente se muestran las constantes de configuración de Java para una aplicación demonio:
private final static String CLIENT_ID = "";
private final static String AUTHORITY = "https://login.microsoftonline.com/<tenant>/";
private final static String CLIENT_SECRET = "";
private final static Set<String> SCOPE = Collections.singleton("https://graph.microsoft.com/.default");
Los parámetros de configuración para el ejemplo de daemon de Node.js se encuentran en un archivo .env:
# 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 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" ],
"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"
}
Este es un ejemplo de cómo definir la configuración en un archivo de configuración appsettings.json de un daemon de consola. 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.
Agregue el paquete NuGet Microsoft.Identity.Web.TokenAcquisition a la aplicación.
Como alternativa, si deseara llamar a Microsoft Graph, agregue el paquete Microsoft.Identity.Web.GraphServiceClient.
El proyecto podría ser como sigue. El archivo appsettings.json debe copiarse en el directorio de salida.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<RootNamespace>daemon_console</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Identity.Web.GraphServiceClient" Version="2.12.2" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
En el archivo Program.cs, agregue una directiva using en el código para hacer referencia a Microsoft.Identity.Web.
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web;
import com.microsoft.aad.msal4j.ClientCredentialFactory;
import com.microsoft.aad.msal4j.ClientCredentialParameters;
import com.microsoft.aad.msal4j.ConfidentialClientApplication;
import com.microsoft.aad.msal4j.IAuthenticationResult;
import com.microsoft.aad.msal4j.IClientCredential;
import com.microsoft.aad.msal4j.MsalException;
import com.microsoft.aad.msal4j.SilentParameters;
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');
Importe los módulos auxiliares y MSAL necesarios en la aplicación de Python:
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:
En el ejemplo siguiente se crea la aplicación cliente confidencial mediante un secreto de cliente con Microsoft. Identity.Web:
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();
// ...
}
}
La configuración se lee desde appsettings.json:
Use el código de Java siguiente para crear una aplicación cliente confidencial con un secreto de cliente:
IClientCredential credential = ClientCredentialFactory.createFromSecret(CLIENT_SECRET);
ConfidentialClientApplication cca =
ConfidentialClientApplication
.builder(CLIENT_ID, credential)
.authority(AUTHORITY)
.build();
Use la siguiente configuración de Node.js para crear instancias de una aplicación cliente confidencial con un secreto de cliente:
const msalConfig = {
auth: {
clientId: process.env.CLIENT_ID,
authority: process.env.AAD_ENDPOINT + process.env.TENANT_ID,
clientSecret: process.env.CLIENT_SECRET,
}
};
const apiConfig = {
uri: process.env.GRAPH_ENDPOINT + 'v1.0/users',
};
const tokenRequest = {
scopes: [process.env.GRAPH_ENDPOINT + '.default'],
};
const cca = new msal.ConfidentialClientApplication(msalConfig);
# 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
)
En el ejemplo MSAL.NET siguiente se crea una aplicación cliente confidencial mediante el secreto de cliente configurado:
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
.WithClientSecret(config.ClientSecret)
.WithAuthority(new Uri(config.Authority))
.Build();
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 de construcción de la aplicación es el mismo que el ejemplo de secreto de cliente. La única diferencia es que el certificado se describe en la configuración en lugar de un secreto.
Hay muchas maneras de obtener el certificado. Para obtener más información, consulte Uso de certificados con Microsoft Identity Web.
En el ejemplo de configuración siguiente se muestra cómo recuperar el certificado de Azure Key Vault. 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. Puede depurar su aplicación localmente porque DefaultAzureCredential usa sus credenciales de desarrollador.
"ClientCredentials": [
{
"SourceType": "KeyVault",
"KeyVaultUrl": "https://yourKeyVaultUrl.vault.azure.net",
"KeyVaultCertificateName": "NameOfYourCertificate"
}
En MSAL Java hay dos generadores para crear una instancia de la aplicación cliente confidencial con certificados:
InputStream pkcs12Certificate = ... ; /* Containing PCKS12-formatted certificate*/
string certificatePassword = ... ; /* Contains the password to access the certificate */
IClientCredential credential = ClientCredentialFactory.createFromCertificate(pkcs12Certificate, certificatePassword);
ConfidentialClientApplication cca =
ConfidentialClientApplication
.builder(CLIENT_ID, credential)
.authority(AUTHORITY)
.build();
o
PrivateKey key = getPrivateKey(); /* RSA private key to sign the assertion */
X509Certificate publicCertificate = getPublicCertificate(); /* x509 public certificate used as a thumbprint */
IClientCredential credential = ClientCredentialFactory.createFromCertificate(key, publicCertificate);
ConfidentialClientApplication cca =
ConfidentialClientApplication
.builder(CLIENT_ID, credential)
.authority(AUTHORITY)
.build();
En el ejemplo de Node.js siguiente se configura una aplicación cliente confidencial para usar un certificado:
const config = {
auth: {
clientId: process.env.CLIENT_ID,
authority: process.env.AAD_ENDPOINT + process.env.TENANT_ID,
clientCertificate: {
thumbprint: process.env.CERTIFICATE_THUMBPRINT, // a 40-digit hexadecimal string
privateKey: process.env.CERTIFICATE_PRIVATE_KEY,
}
}
};
// Create an MSAL application object
const cca = new msal.ConfidentialClientApplication(config);
Para más información, consulte Uso de credenciales de certificado con MSAL Node.
# 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
)
Use el código MSAL.NET siguiente para cargar un certificado y compilar la aplicación cliente confidencial:
X509Certificate2 certificate = ReadCertificate(config.CertificateName);
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
.WithCertificate(certificate)
.WithAuthority(new Uri(config.Authority))
.Build();
Escenario avanzado: Creación de una instancia de aplicación cliente confidencial con aserciones de cliente
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 el ejemplo Java siguiente se crea una aplicación cliente confidencial mediante una aserción de cliente:
IClientCredential credential = ClientCredentialFactory.createFromClientAssertion(assertion);
ConfidentialClientApplication cca =
ConfidentialClientApplication
.builder(CLIENT_ID, credential)
.authority(AUTHORITY)
.build();
Use la siguiente configuración de Node.js para inicializar una aplicación cliente confidencial con una aserción de cliente:
const clientConfig = {
auth: {
clientId: process.env.CLIENT_ID,
authority: process.env.AAD_ENDPOINT + process.env.TENANT_ID,
clientAssertion: process.env.CLIENT_ASSERTION
}
};
const cca = new msal.ConfidentialClientApplication(clientConfig);
Para obtener más información, consulte Inicializar el objeto ConfidentialClientApplication.
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
)
Para más información, consulte la documentación de referencia de MSAL Python para ConfidentialClientApplication.
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.
string signedClientAssertion = ComputeAssertion();
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
.WithClientAssertion(signedClientAssertion)
.Build();
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:
string ipAddress = "192.168.1.2";
var claims = new Dictionary<string, string> { { "client_ip", ipAddress } };
X509Certificate2 certificate = ReadCertificate(config.CertificateName);
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
.WithAuthority(new Uri(config.Authority))
.WithClientClaims(certificate, claims)
.Build();
Para más información, consulte Aserciones de cliente.
Pasos siguientes