Configurar el inicio de sesión único basado en SAML para su aplicación con la API de Microsoft Graph
Artículo
En este artículo, aprenderá a crear y configurar un inicio de sesión único basado en SAML (SSO) para su aplicación en Azure Active Directory (Azure AD) mediante la API de Microsoft Graph. La configuración de la aplicación incluye direcciones URL SAML básicas, una directiva de asignación de notificaciones y un certificado para agregar una clave de firma personalizada. Una vez creada la aplicación, debe asignarle un usuario para que haga de administrador. Después, puede usar una dirección URL para obtener metadatos de Azure AD SAML para la configuración adicional de la aplicación.
El presente artículo usa una plantilla de aplicación AWS Azure AD como ejemplo, pero puede usar estos pasos para cualquier aplicación basada en SAML en la galería de Azure AD.
Requisitos previos
Inicie sesión en un cliente de API como Graph Explorer, Postman o cree su propia aplicación cliente para llamar a Microsoft Graph. Para llamar a las API de Microsoft Graph en este tutorial, debe usar una cuenta con el rol de administrador global.
Concédese los siguientes permisos delegados: Application.ReadWrite.All, AppRoleAssignment.ReadWrite.All, Policy.Read.All, Policy.ReadWrite.ApplicationConfigurationy User.ReadWrite.All.
Paso 1: Crear la aplicación
Azure AD tiene una galería con miles de aplicaciones integradas que puede usar como plantilla para la aplicación. La plantilla de la aplicación describe los metadatos de esa aplicación. Con esta plantilla, puede crear una instancia de la aplicación y de la entidad de servicio en su espacio empresarial para administrarlas.
Para crear la aplicación desde la galería, primero obtenga el identificador de la plantilla de aplicación y, después, use ese identificador para crear la aplicación.
Recupere el identificador de plantilla de la aplicación de la galería
En este tutorial, recuperará el identificador de la plantilla de la aplicación para AWS IAM Identity Center (successor to AWS Single Sign-On). A continuación, registre el valor de la propiedad id para usarlo más adelante en este tutorial.
GET https://graph.microsoft.com/v1.0/applicationTemplates?$filter=displayName eq 'AWS IAM Identity Center (successor to AWS Single Sign-On)'
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var result = await graphClient.ApplicationTemplates.GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Filter = "displayName eq 'AWS IAM Identity Center '";
});
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestConfiguration = new ApplicationTemplatesRequestBuilderGetRequestConfiguration();
$queryParameters = ApplicationTemplatesRequestBuilderGetRequestConfiguration::createQueryParameters();
$queryParameters->filter = "displayName eq 'AWS IAM Identity Center '";
$requestConfiguration->queryParameters = $queryParameters;
$result = $graphServiceClient->applicationTemplates()->get($requestConfiguration);
Import-Module Microsoft.Graph.Applications
Get-MgApplicationTemplate -Filter "displayName eq 'AWS IAM Identity Center (successor to AWS Single Sign-On)'"
HTTP/1.1 200 OK
Content-type: application/json
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#applicationTemplates",
"value": [
{
"id": "21ed01d2-ec13-4e9e-86c1-cd546719ebc4",
"displayName": "AWS IAM Identity Center (successor to AWS Single Sign-On)",
"homePageUrl": "https://aws.amazon.com/",
"supportedSingleSignOnModes": [
"saml",
"external"
],
"supportedProvisioningTypes": [
"sync"
],
"logoUrl": "https://az495088.vo.msecnd.net/app-logo/awssinglesignon_215.png",
"categories": [
"developerServices",
"itInfrastructure",
"security",
"New"
],
"publisher": "Amazon Web Services, Inc.",
"description": "Federate once to AWS IAM Identity Center (successor to AWS Single Sign-On) & use it to centrally manage access to multiple AWS accounts and IAM Identity Center enabled apps. Provision users via SCIM."
}
]
}
Crear la aplicación
Con el id. que agregó para la plantilla de la aplicación, cree una instancia de la entidad de servicio y la aplicación en su espacio empresarial. Registre el valor de la propiedad Id de la aplicación y el valor de la propiedad Id de la entidad de servicio.para ser usados más adelante,
POST https://graph.microsoft.com/v1.0/applicationTemplates/21ed01d2-ec13-4e9e-86c1-cd546719ebc4/instantiate
Content-type: application/json
{
"displayName": "AWS Contoso"
}
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new Microsoft.Graph.ApplicationTemplates.Item.Instantiate.InstantiatePostRequestBody
{
DisplayName = "AWS Contoso",
};
var result = await graphClient.ApplicationTemplates["{applicationTemplate-id}"].Instantiate.PostAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new InstantiatePostRequestBody();
$requestBody->setDisplayName('AWS Contoso');
$result = $graphServiceClient->applicationTemplates()->byApplicationTemplateId('applicationTemplate-id')->instantiate()->post($requestBody);
Dé un margen de tiempo para que se aprovisione la aplicación en su inquilino de Azure AD. No sucede de manera instantánea. Una estrategia puede ser realizar una consulta GET en la aplicación o en el objeto de la entidad de servicio cada 5-10 segundos hasta que la consulta se realice correctamente.
En este tutorial, establecerá saml como el inicio de sesión único en la entidad de servicio. Use el Id para la entidad de servicio que agregó anteriormente.
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new ServicePrincipal
{
PreferredSingleSignOnMode = "saml",
};
var result = await graphClient.ServicePrincipals["{servicePrincipal-id}"].PatchAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new ServicePrincipal();
$requestBody->setPreferredSingleSignOnMode('saml');
$result = $graphServiceClient->servicePrincipals()->byServicePrincipalId('servicePrincipal-id')->patch($requestBody);
Use el Id para la aplicación que registró anteriormente para establecer el identificador URI y redirija el identificador URI de AWS en el objeto de aplicación.
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new Application
{
Web = new WebApplication
{
RedirectUris = new List<string>
{
"https://signin.aws.amazon.com/saml",
},
},
IdentifierUris = new List<string>
{
"https://signin.aws.amazon.com/saml",
},
};
var result = await graphClient.Applications["{application-id}"].PatchAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new Application();
$web = new WebApplication();
$web->setRedirectUris(['https://signin.aws.amazon.com/saml', ]);
$requestBody->setWeb($web);
$requestBody->setIdentifierUris(['https://signin.aws.amazon.com/saml', ]);
$result = $graphServiceClient->applications()->byApplicationId('application-id')->patch($requestBody);
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new ServicePrincipal
{
AppRoles = new List<AppRole>
{
new AppRole
{
AllowedMemberTypes = new List<string>
{
"User",
},
DisplayName = "User",
Id = Guid.Parse("8774f594-1d59-4279-b9d9-59ef09a23530"),
IsEnabled = true,
Description = "User",
Value = null,
Origin = "Application",
},
new AppRole
{
AllowedMemberTypes = new List<string>
{
"User",
},
DisplayName = "msiam_access",
Id = Guid.Parse("e7f1a7f3-9eda-48e0-9963-bd67bf531afd"),
IsEnabled = true,
Description = "msiam_access",
Value = null,
Origin = "Application",
},
new AppRole
{
AllowedMemberTypes = new List<string>
{
"User",
},
Description = "Admin,WAAD",
DisplayName = "Admin,WAAD",
Id = Guid.Parse("3a84e31e-bffa-470f-b9e6-754a61e4dc63"),
IsEnabled = true,
Value = "arn:aws:iam::212743507312:role/accountname-aws-admin,arn:aws:iam::212743507312:saml-provider/WAAD",
},
new AppRole
{
AllowedMemberTypes = new List<string>
{
"User",
},
Description = "Finance,WAAD",
DisplayName = "Finance,WAAD",
Id = Guid.Parse("7a960000-ded3-455b-8c04-4f2ace00319b"),
IsEnabled = true,
Value = "arn:aws:iam::212743507312:role/accountname-aws-finance,arn:aws:iam::212743507312:saml-provider/WAAD",
},
},
};
var result = await graphClient.ServicePrincipals["{servicePrincipal-id}"].PatchAsync(requestBody);
Algunas claves de la directiva de asignación de notificaciones distinguen entre mayúsculas y minúsculas (por ejemplo, "Versión"). Si recibe un mensaje de error como "La propiedad tiene un valor no válido", puede deberse a la diferenciación entre mayúsculas y minúsculas.
Cree la directiva de asignación de notificaciones y registre el valor de la propiedad id para usarlo más adelante en este tutorial.
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new ClaimsMappingPolicy
{
Definition = new List<string>
{
"{\"ClaimsMappingPolicy\":{\"Version\":1,\"IncludeBasicClaimSet\":\"true\", \"ClaimsSchema\": [{\"Source\":\"user\",\"ID\":\"assignedroles\",\"SamlClaimType\": \"https://aws.amazon.com/SAML/Attributes/Role\"}, {\"Source\":\"user\",\"ID\":\"userprincipalname\",\"SamlClaimType\": \"https://aws.amazon.com/SAML/Attributes/RoleSessionName\"}, {\"Value\":\"900\",\"SamlClaimType\": \"https://aws.amazon.com/SAML/Attributes/SessionDuration\"}, {\"Source\":\"user\",\"ID\":\"assignedroles\",\"SamlClaimType\": \"appRoles\"}, {\"Source\":\"user\",\"ID\":\"userprincipalname\",\"SamlClaimType\": \"https://aws.amazon.com/SAML/Attributes/nameidentifier\"}]}}",
},
DisplayName = "AWS Claims Policy",
IsOrganizationDefault = false,
};
var result = await graphClient.Policies.ClaimsMappingPolicies.PostAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new ClaimsMappingPolicy();
$requestBody->setDefinition(['{\"ClaimsMappingPolicy\":{\"Version\":1,\"IncludeBasicClaimSet\":\"true\", \"ClaimsSchema\": [{\"Source\":\"user\",\"ID\":\"assignedroles\",\"SamlClaimType\": \"https://aws.amazon.com/SAML/Attributes/Role\"}, {\"Source\":\"user\",\"ID\":\"userprincipalname\",\"SamlClaimType\": \"https://aws.amazon.com/SAML/Attributes/RoleSessionName\"}, {\"Value\":\"900\",\"SamlClaimType\": \"https://aws.amazon.com/SAML/Attributes/SessionDuration\"}, {\"Source\":\"user\",\"ID\":\"assignedroles\",\"SamlClaimType\": \"appRoles\"}, {\"Source\":\"user\",\"ID\":\"userprincipalname\",\"SamlClaimType\": \"https://aws.amazon.com/SAML/Attributes/nameidentifier\"}]}}', ]);
$requestBody->setDisplayName('AWS Claims Policy');
$requestBody->setIsOrganizationDefault(false);
$result = $graphServiceClient->policies()->claimsMappingPolicies()->post($requestBody);
Asignar la directiva de asignación de notificaciones a la entidad de servicio
Use el Id para la entidad de servicio que registró anteriormente para asignar una directiva de asignación de notificaciones. Use el valor de la propiedad id. de la directiva de asignación de notificaciones en el cuerpo de la solicitud.
POST https://graph.microsoft.com/v1.0/servicePrincipals/a750f6cf-2319-464a-bcc3-456926736a91/claimsMappingPolicies/$ref
Content-type: application/json
{
"@odata.id":"https://graph.microsoft.com/v1.0/policies/claimsMappingPolicies/a4b35718-fd5e-4ca8-8248-a3c9934b1b78"
}
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new Microsoft.Graph.Models.ReferenceCreate
{
OdataId = "https://graph.microsoft.com/v1.0/policies/claimsMappingPolicies/a4b35718-fd5e-4ca8-8248-a3c9934b1b78",
};
await graphClient.ServicePrincipals["{servicePrincipal-id}"].ClaimsMappingPolicies.Ref.PostAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new ReferenceCreate();
$requestBody->set@odataid('https://graph.microsoft.com/v1.0/policies/claimsMappingPolicies/a4b35718-fd5e-4ca8-8248-a3c9934b1b78');
$graphServiceClient->servicePrincipals()->byServicePrincipalId('servicePrincipal-id')->claimsMappingPolicies()->ref()->post($requestBody);
Necesitará un certificado autofirmado que Azure AD pueda usar para firmar una respuesta SAML. Puede usar su propio certificado o puede usar el siguiente ejemplo.
Opción 1: Creación de un certificado de firma en Azure AD
Con el Id de la entidad de servicio que ha creado, cree un nuevo certificado y agrégrelo a la entidad de servicio.
POST https://graph.microsoft.com/v1.0/servicePrincipals/a750f6cf-2319-464a-bcc3-456926736a91/addTokenSigningCertificate
Content-type: application/json
{
"displayName":"CN=AWSContoso",
"endDateTime":"2024-01-25T00:00:00Z"
}
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new Microsoft.Graph.ServicePrincipals.Item.AddTokenSigningCertificate.AddTokenSigningCertificatePostRequestBody
{
DisplayName = "CN=AWSContoso",
EndDateTime = DateTimeOffset.Parse("2024-01-25T00:00:00Z"),
};
var result = await graphClient.ServicePrincipals["{servicePrincipal-id}"].AddTokenSigningCertificate.PostAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new AddTokenSigningCertificatePostRequestBody();
$requestBody->setDisplayName('CN=AWSContoso');
$requestBody->setEndDateTime(new DateTime('2024-01-25T00:00:00Z'));
$result = $graphServiceClient->servicePrincipals()->byServicePrincipalId('servicePrincipal-id')->addTokenSigningCertificate()->post($requestBody);
Opción 2: Crear un certificado de firma personalizado
Puede usar los siguientes scripts de PowerShell y C# para obtener un certificado autofirmado para las pruebas. Después, tendrá que manipular y extraer manualmente los valores que necesita mediante otras herramientas. Emplee el procedimiento de seguridad recomendado de su empresa para crear un certificado de firma para producción.
La siguiente aplicación de consola de C# se puede usar como prueba de concepto para comprender cómo se pueden obtener los valores necesarios. Este código es solo para aprendizaje y referencia y no debe usarse tal cual en producción.
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
/* CONSOLE APP - PROOF OF CONCEPT CODE ONLY!!
* This code uses a self signed certificate and should not be used
* in production. This code is for reference and learning ONLY.
*/
namespace Self_signed_cert
{
class Program
{
static void Main(string[] args)
{
// Generate a guid to use as a password and then create the cert.
string password = Guid.NewGuid().ToString();
var selfsignedCert = buildSelfSignedServerCertificate(password);
// Print values so we can copy paste into the JSON fields.
// Print out the private key in base64 format.
Console.WriteLine("Private Key: {0}{1}", Convert.ToBase64String(selfsignedCert.Export(X509ContentType.Pfx, password)), Environment.NewLine);
// Print out the start date in ISO 8601 format.
DateTime startDate = DateTime.Parse(selfsignedCert.GetEffectiveDateString()).ToUniversalTime();
Console.WriteLine("For All startDateTime: " + startDate.ToString("o"));
// Print out the end date in ISO 8601 format.
DateTime endDate = DateTime.Parse(selfsignedCert.GetExpirationDateString()).ToUniversalTime();
Console.WriteLine("For All endDateTime: " + endDate.ToString("o"));
// Print the GUID used for keyId
string signAndPasswordGuid = Guid.NewGuid().ToString();
string verifyGuid = Guid.NewGuid().ToString();
Console.WriteLine("GUID to use for keyId for keyCredentials->Usage == Sign and passwordCredentials: " + signAndPasswordGuid);
Console.WriteLine("GUID to use for keyId for keyCredentials->Usage == Verify: " + verifyGuid);
// Print out the password.
Console.WriteLine("Password is: {0}", password);
// Print out a displayName to use as an example.
Console.WriteLine("displayName to use: CN=Example");
Console.WriteLine();
// Print out the public key.
Console.WriteLine("Public Key: {0}{1}", Convert.ToBase64String(selfsignedCert.Export(X509ContentType.Cert)), Environment.NewLine);
Console.WriteLine();
// Generate the customKeyIdentifier using hash of thumbprint.
Console.WriteLine("You can generate the customKeyIdentifier by getting the SHA256 hash of the certs thumprint.\nThe certs thumbprint is: {0}{1}", selfsignedCert.Thumbprint, Environment.NewLine);
Console.WriteLine("The hash of the thumbprint that we will use for customeKeyIdentifier is:");
string keyIdentifier = GetSha256FromThumbprint(selfsignedCert.Thumbprint);
Console.WriteLine(keyIdentifier);
}
// Generate a self-signed certificate.
private static X509Certificate2 buildSelfSignedServerCertificate(string password)
{
const string CertificateName = @"Microsoft Azure Federated SSO Certificate TEST";
DateTime certificateStartDate = DateTime.UtcNow;
DateTime certificateEndDate = certificateStartDate.AddYears(2).ToUniversalTime();
X500DistinguishedName distinguishedName = new X500DistinguishedName($"CN={CertificateName}");
using (RSA rsa = RSA.Create(2048))
{
var request = new CertificateRequest(distinguishedName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
request.CertificateExtensions.Add(
new X509KeyUsageExtension(X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature, false));
var certificate = request.CreateSelfSigned(new DateTimeOffset(certificateStartDate), new DateTimeOffset(certificateEndDate));
certificate.FriendlyName = CertificateName;
return new X509Certificate2(certificate.Export(X509ContentType.Pfx, password), password, X509KeyStorageFlags.Exportable);
}
}
// Generate hash from thumbprint.
public static string GetSha256FromThumbprint(string thumbprint)
{
var message = Encoding.ASCII.GetBytes(thumbprint);
SHA256Managed hashString = new SHA256Managed();
return Convert.ToBase64String(hashString.ComputeHash(message));
}
}
}
Agregar una clave de firma personalizada
Después de ejecutar el código anterior, extraiga los valores de los parámetros siguientes del archivo PFX. Agregará esta información a la entidad de servicio:
Asegúrese de que el keyId del keyCredential usado para "Sign" coincide con el keyId de passwordCredential. Puede generar customkeyIdentifier mediante la obtención del hash de la huella digital del certificado. Vea el código C# de referencia anterior.
Solicitud
Nota:
Se ha abreviado el valor "clave" en la propiedad keyCredentials para facilitar la lectura. El valor está codificado en base 64. Para la clave privada, la propiedad usage es "Sign". Para la clave pública, la propiedad usage es "Verify".
Debe establecer la propiedad PreferredTokenSigningKeyThumbprint de la entidad de servicio con la huella digital del certificado que quiere que use Azure AD para firmar la respuesta SAML.
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new ServicePrincipal
{
PreferredTokenSigningKeyThumbprint = "A7D3C4626B8A84FDA868CCC67D274D402FFD0A10",
};
var result = await graphClient.ServicePrincipals["{servicePrincipal-id}"].PatchAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new ServicePrincipal();
$requestBody->setPreferredTokenSigningKeyThumbprint('A7D3C4626B8A84FDA868CCC67D274D402FFD0A10');
$result = $graphServiceClient->servicePrincipals()->byServicePrincipalId('servicePrincipal-id')->patch($requestBody);
Para este tutorial, debe crear una cuenta de usuario que se agrega a la aplicación. En el cuerpo de la solicitud, cambie contoso.com por el nombre de dominio de su espacio empresarial. Puede encontrar la información del espacio empresarial en la página de información general de Azure Active Directory. Registre el id. del usuario que se usará más adelante en el tutorial.
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new User
{
AccountEnabled = true,
DisplayName = "MyTestUser1",
MailNickname = "MyTestUser1",
UserPrincipalName = "MyTestUser1@contoso.com",
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = true,
Password = "Contoso1234",
},
};
var result = await graphClient.Users.PostAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestBody = new User();
$requestBody->setAccountEnabled(true);
$requestBody->setDisplayName('MyTestUser1');
$requestBody->setMailNickname('MyTestUser1');
$requestBody->setUserPrincipalName('MyTestUser1@contoso.com');
$passwordProfile = new PasswordProfile();
$passwordProfile->setForceChangePasswordNextSignIn(true);
$passwordProfile->setPassword('Contoso1234');
$requestBody->setPasswordProfile($passwordProfile);
$result = $graphServiceClient->users()->post($requestBody);
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new AppRoleAssignment
{
PrincipalId = Guid.Parse("040f9599-7c0f-4f94-aa75-8394c4c6ea9b"),
PrincipalType = "User",
AppRoleId = Guid.Parse("3a84e31e-bffa-470f-b9e6-754a61e4dc63"),
ResourceId = Guid.Parse("a750f6cf-2319-464a-bcc3-456926736a91"),
};
var result = await graphClient.ServicePrincipals["{servicePrincipal-id}"].AppRoleAssignments.PostAsync(requestBody);
Utilice la siguiente dirección URL para obtener los metadatos SAML de Azure AD para la aplicación configurada específica. Los metadatos contienen información como el certificado de firma, Azure AD entityID y Azure AD SingleSignOnService, entre otros.
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
await graphClient.Applications["{application-id}"].DeleteAsync();
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$graphServiceClient->applications()->byApplicationId('application-id')->delete();
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
await graphClient.Users["{user-id}"].DeleteAsync();
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$graphServiceClient->users()->byUserId('user-id')->delete();
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
await graphClient.Policies.ClaimsMappingPolicies["{claimsMappingPolicy-id}"].DeleteAsync();
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$graphServiceClient->policies()->claimsMappingPolicies()->byClaimsMappingPolicieId('claimsMappingPolicy-id')->delete();
Puede usar la API applicationTemplate para generar instancias de Aplicaciones situadas fuera de la Galería. Utilice applicationTemplateId 8adf8e6e-67b2-4cf2-a259-e3dc5476c621.