Настройка единого входа на основе SAML для приложения с помощью API Microsoft Graph
Статья
В этой статье вы узнаете, как создать и настроить единый вход на основе SAML для приложения в Azure Active Directory (Azure AD) с помощью API Microsoft Graph. Конфигурация приложения включает основные URL-адреса SAML, политику сопоставления утверждений и использование сертификата для добавления пользовательского ключа подписи. После создания приложения назначьте для него пользователя, который будет администратором. После этого вы сможете использовать URL-адрес, чтобы получить метаданные SAML AD Azure для дополнительной настройки приложения.
В этой статье в качестве примера используется шаблон приложения Azure AD AWS, но описанные здесь шаги можно применить для любого другого приложения на основе SAML, включенного в коллекцию Azure AD.
Предварительные требования
Войдите в клиент API, например Graph Обозреватель, Postman, или создайте собственное клиентское приложение для вызова Microsoft Graph. Чтобы вызвать API Microsoft Graph в этом руководстве, необходимо использовать учетную запись с ролью глобального администратора.
Предоставьте себе следующие делегированные разрешения: Application.ReadWrite.All, AppRoleAssignment.ReadWrite.All, Policy.Read.All, Policy.ReadWrite.ApplicationConfigurationи User.ReadWrite.All.
Шаг 1. Создание приложения
В Azure AD есть коллекция, содержащая тысячи предварительно интегрированных приложений, которые можно использовать в качестве шаблонов для приложения. В шаблоне приложения описаны метаданные для этого приложения. По этому шаблону вы можете создать экземпляр приложения и субъект-службу в клиенте для управления им.
Чтобы создать приложение из коллекции, сначала получите идентификатор шаблона приложения и используйте его для создания приложения.
Получение идентификатора шаблона для приложения из коллекции
В этом руководстве вы получаете идентификатор шаблона приложения для AWS IAM Identity Center (successor to AWS Single Sign-On). Запишите значение свойства id, которое понадобится позже в этом руководстве.
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 (successor to AWS Single Sign-On)'";
});
Import-Module Microsoft.Graph.Applications
Get-MgApplicationTemplate -Filter "displayName eq 'AWS IAM Identity Center (successor to AWS Single Sign-On)'"
<?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 (successor to AWS Single Sign-On)'";
$requestConfiguration->queryParameters = $queryParameters;
$result = $graphServiceClient->applicationTemplates()->get($requestConfiguration);
// THE PYTHON SDK IS IN PREVIEW. NON-PRODUCTION USE ONLY
client = GraphServiceClient(request_adapter)
query_params = ApplicationTemplatesRequestBuilder.ApplicationTemplatesRequestBuilderGetQueryParameters(
filter = "displayName eq 'AWS IAM Identity Center (successor to AWS Single Sign-On)'",
)
request_configuration = ApplicationTemplatesRequestBuilder.ApplicationTemplatesRequestBuilderGetRequestConfiguration(
query_parameters = query_params,
)
result = await client.application_templates.get(request_configuration = request_configuration)
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."
}
]
}
Создание приложения
Используя значение id, записанное для шаблона приложения, создайте экземпляр приложения и субъект-службу в клиенте. Запишите значение свойства id приложения и значение свойства id для субъект-службы, чтобы применить их позже в этом руководстве.
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);
// THE PYTHON SDK IS IN PREVIEW. NON-PRODUCTION USE ONLY
client = GraphServiceClient(request_adapter)
request_body = InstantiatePostRequestBody()
request_body.display_name = 'AWS Contoso'
result = await client.application_templates.by_application_template_id('applicationTemplate-id').instantiate.post(request_body = request_body)
Подождите некоторое время, пока приложение будет подготовлено в клиенте Azure AD. Это не происходит сразу. Одной из стратегий является выполнение запроса GET для объекта приложения или субъекта-службы каждые 5–10 секунд до тех пор, пока запрос не будет успешным.
В этом руководстве вы настраиваете saml в качестве режима единого входа для субъекта-службы. Используйте значение id для субъект-службы, записанное ранее.
// 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);
// THE PYTHON SDK IS IN PREVIEW. NON-PRODUCTION USE ONLY
client = GraphServiceClient(request_adapter)
request_body = ServicePrincipal()
request_body.preferred_single_sign_on_mode = 'saml'
result = await client.service_principals.by_service_principal_id('servicePrincipal-id').patch(request_body = request_body)
// 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);
// THE PYTHON SDK IS IN PREVIEW. NON-PRODUCTION USE ONLY
client = GraphServiceClient(request_adapter)
request_body = Application()
web = WebApplication()
web.RedirectUris(['https://signin.aws.amazon.com/saml', ])
request_body.web = web
request_body.IdentifierUris(['https://signin.aws.amazon.com/saml', ])
result = await client.applications.by_application_id('application-id').patch(request_body = request_body)
// 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);
Некоторые ключи в политике сопоставления утверждений чувствительны к регистру (например, "Version"). Если появляется сообщение об ошибке "Свойство имеет недопустимое значение", это может быть проблема, связанная с регистром.
Создайте политику сопоставления утверждений и запишите значение свойства id, которое понадобится позже в этом руководстве.
// 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);
Назначение политики сопоставления утверждений субъекту-службе
Используйте значение id для субъект-службы, записанное ранее, чтобы назначить ему политику сопоставления утверждений. В тексте запроса используйте значение свойства id для политики сопоставления утверждений.
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);
// THE PYTHON SDK IS IN PREVIEW. NON-PRODUCTION USE ONLY
client = GraphServiceClient(request_adapter)
request_body = ReferenceCreate()
request_body.@odata_id = 'https://graph.microsoft.com/v1.0/policies/claimsMappingPolicies/a4b35718-fd5e-4ca8-8248-a3c9934b1b78'
await client.service_principals.by_service_principal_id('servicePrincipal-id').claim_mapping_policies.ref.post(request_body = request_body)
Вам потребуется самозаверяющий сертификат, с помощью которого Azure AD может подписать отклик SAML. Вы можете использовать свой собственный сертификат или использовать пример ниже.
Вариант 1. Создание сертификата подписи в Azure AD
Используя id созданной вами субъект-службы, создайте новый сертификат и добавьте его к субъект-службе.
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);
// THE PYTHON SDK IS IN PREVIEW. NON-PRODUCTION USE ONLY
client = GraphServiceClient(request_adapter)
request_body = AddTokenSigningCertificatePostRequestBody()
request_body.display_name = 'CN=AWSContoso'
request_body.endDateTime = DateTime('2024-01-25T00:00:00Z')
result = await client.service_principals.by_service_principal_id('servicePrincipal-id').add_token_signing_certificate.post(request_body = request_body)
Вариант 2. Создание настраиваемого сертификата подписи
Чтобы получить самозаверяющий сертификат для тестирования, можно использовать следующие скрипты PowerShell и C#. Затем потребуется вручную обработать и извлечь нужные значения с помощью других средств. При создании сертификата для подписи в рабочей среде применяйте все самые передовые рекомендации по безопасности, используемые в вашей компании.
Следующее консольное приложение C# можно использовать в качестве подтверждения концепции, чтобы понять, как можно получить необходимые значения. Этот код предназначен только для обучения и ссылки и не должен использоваться в рабочей среде как есть.
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));
}
}
}
Добавление пользовательского ключа подписывания
После выполнения предыдущего кода извлеките значения для следующих параметров из PFX-файла. Вы добавите следующие сведения в субъект-службу:
Убедитесь, что значение keyId для keyCredential, примененное для параметра Sign, соответствует значению keyId для passwordCredential. Вы можете создать customkeyIdentifier, получив хэш отпечатка сертификата. См. предыдущий код ссылки C#.
Запрос
Примечание.
Значение key в свойстве keyCredentials сокращено для удобства чтения. Значение представлено в кодировке Base 64. Для закрытого ключа свойство usage имеет значение "Sign". Для открытого ключа свойство usage имеет значение "Verify".
Присвойте свойству preferredTokenSigningKeyThumbprint субъекта-службы значение отпечатка сертификата, который должен использоваться в Azure AD для подписи отклика 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);
// THE PYTHON SDK IS IN PREVIEW. NON-PRODUCTION USE ONLY
client = GraphServiceClient(request_adapter)
request_body = ServicePrincipal()
request_body.preferred_token_signing_key_thumbprint = 'A7D3C4626B8A84FDA868CCC67D274D402FFD0A10'
result = await client.service_principals.by_service_principal_id('servicePrincipal-id').patch(request_body = request_body)
В этом руководстве создается учетная запись пользователя, которая добавляется в приложение. В тексте запроса измените contoso.com на доменное имя своего клиента. Информацию о клиенте можно найти на странице обзора в Azure Active Directory. Запишите id пользователя, чтобы применить его позднее в этом руководстве.
// 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);
Используйте следующий URL-адрес, чтобы получить метаданные SAML из Azure AD для конкретного настроенного приложения. Эти метаданные содержат такие сведения, как сертификат для подписи, идентификатор сущности Azure AD (entityID), служба единого входа Azure AD (SingleSignOnService) и т. д.
// 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();
// THE PYTHON SDK IS IN PREVIEW. NON-PRODUCTION USE ONLY
client = GraphServiceClient(request_adapter)
await client.applications.by_application_id('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();
// THE PYTHON SDK IS IN PREVIEW. NON-PRODUCTION USE ONLY
client = GraphServiceClient(request_adapter)
await client.users.by_user_id('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();
// THE PYTHON SDK IS IN PREVIEW. NON-PRODUCTION USE ONLY
client = GraphServiceClient(request_adapter)
await client.policies.claim_mapping_policies.by_claim_mapping_policie_id('claimsMappingPolicy-id').delete()
Вы можете использовать API applicationTemplate для создания экземпляров приложений не из коллекции. Используйте applicationTemplateId 8adf8e6e-67b2-4cf2-a259-e3dc5476c621.