Добавление сертификата в приложение с помощью Microsoft Graph
Статья
Платформа удостоверений Майкрософт поддерживает три типа учетных данных для проверки подлинности приложений и субъектов-служб: пароли (секреты приложений), сертификаты и учетные данные федеративного удостоверения. Если вы не можете использовать учетные данные федеративного удостоверения для приложения, настоятельно рекомендуется использовать сертификаты вместо секретов.
В этой статье содержатся рекомендации по использованию сценариев Microsoft Graph и PowerShell для программного обновления учетных данных сертификата для регистрации приложения.
Предварительные условия
Для работы с этим руководством вам потребуются следующие ресурсы и привилегии:
Активный клиент Microsoft Entra.
Клиент API, например Graph Обозреватель. Войдите как пользователь, которому разрешено создавать приложения в клиенте и управлять ими.
Роль "Разработчик приложений" (приложения, которым они владеют) и "Администратор приложения", являются наименее привилегированными ролями, которые могут выполнять эту операцию.
Настоятельно рекомендуется использовать сертификаты вместо секретов; Однако мы не рекомендуем использовать самозаверяемые сертификаты. Они могут снизить уровень безопасности приложения из-за различных факторов, таких как использование устаревших наборов хэша и шифров или отсутствие проверки. Рекомендуется приобретать сертификаты из хорошо известного доверенного центра сертификации.
Шаг 1. Чтение сведений о сертификате
Чтобы добавить сертификат программным способом с помощью Microsoft Graph, вам потребуется ключ сертификата. При необходимости можно добавить отпечаток сертификата.
[Необязательно] Получение отпечатка сертификата
Необязательно добавить отпечаток сертификата в полезные данные запроса. Если вы хотите добавить отпечаток, можно выполнить следующий запрос PowerShell, чтобы прочитать отпечаток сертификата. Этот запрос предполагает, что вы создали и экспортировали сертификат на локальный диск.
Запрос
## Replace the file path with the source of your certificate and output path with the location where you want to save the thumprint details
Get-PfxCertificate -Filepath "C:\Users\admin\Desktop\20230112.cer" | Out-File -FilePath "C:\Users\admin\Desktop\20230112.cer.thumbprint.txt"
Отклик
Выходные данные в файле.txt могут выглядеть следующим образом.
Чтобы прочитать ключ сертификата и сохранить его в файле.txt с помощью PowerShell, выполните следующий запрос.
Запрос
PowerShell < 6:
## Replace the file path with the location of your certificate
[convert]::ToBase64String((Get-Content C:\Users\admin\Desktop\20230112.cer -Encoding byte)) | Out-File -FilePath "C:\Users\admin\Desktop\20230112.key.txt"
PowerShell >= 6:
## Replace the file path with the location of your certificate
[convert]::ToBase64String((Get-Content C:\Users\admin\Desktop\20230112.cer -AsByteStream)) | Out-File -FilePath "C:\Users\admin\Desktop\20230112.key.txt"
Отклик
Выходные данные в файле.txt могут выглядеть следующим образом.
Заметка: Показанный здесь ключ был сокращен для удобства чтения.
Шаг 2. Добавление сведений о сертификате с помощью Microsoft Graph
Запрос
Следующий запрос добавляет сведения о сертификате в приложение. Ниже приведены параметры.
StartDateTime — это дата создания или после создания сертификата.
Значение endDateTime может быть не более 1 года с момента startDateTime. Если это не указано, система автоматически назначит дату через 1 год после startDateTime.
Тип и использование должны быть AsymmetricX509Cert и Verify соответственно.
Назначьте имя субъекта сертификата свойству displayName .
Ключ — это значение в кодировке Base64, созданное на предыдущем шаге. Отпечаток включается в закодированный ключ, и при добавлении ключа также добавляется отпечаток.
Примечание.
Если в вашем приложении есть действительный сертификат, который вы хотите продолжать использовать для проверки подлинности, добавьте сведения о текущем и новом сертификате в объект keyCredentials приложения. Так как это вызов PATCH, который по протоколу заменяет содержимое свойства новыми значениями, включая только новый сертификат, заменит существующие сертификаты новым.
В следующем примере добавляется новый сертификат и заменяются все существующие сертификаты.
Заметка: Показанный здесь ключ был сокращен для удобства чтения.
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new Application
{
KeyCredentials = new List<KeyCredential>
{
new KeyCredential
{
EndDateTime = DateTimeOffset.Parse("2024-01-11T15:31:26Z"),
StartDateTime = DateTimeOffset.Parse("2023-01-12T15:31:26Z"),
Type = "AsymmetricX509Cert",
Usage = "Verify",
Key = Convert.FromBase64String("base64MIIDADCCAeigAwIBAgIQP6HEGDdZ65xJTcK4dCBvZzANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAgyMDIzMDExMjAeFw0yMzAxMTIwODExNTZaFw0yNDAxMTIwODMxNTZaMBMxETAPBgNVBAMMCDIwMjMwMTEyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAseKf1weEacJ67D6/...laxQPUbuIL+DaXVkKRm1V3GgIpKTBqMzTf4tCpy7rpUZbhcwAFw6h9A=="),
DisplayName = "CN=20230112",
},
},
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Applications["{application-id}"].PatchAsync(requestBody);
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
Application application = new Application();
LinkedList<KeyCredential> keyCredentials = new LinkedList<KeyCredential>();
KeyCredential keyCredential = new KeyCredential();
OffsetDateTime endDateTime = OffsetDateTime.parse("2024-01-11T15:31:26Z");
keyCredential.setEndDateTime(endDateTime);
OffsetDateTime startDateTime = OffsetDateTime.parse("2023-01-12T15:31:26Z");
keyCredential.setStartDateTime(startDateTime);
keyCredential.setType("AsymmetricX509Cert");
keyCredential.setUsage("Verify");
byte[] key = Base64.getDecoder().decode("base64MIIDADCCAeigAwIBAgIQP6HEGDdZ65xJTcK4dCBvZzANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAgyMDIzMDExMjAeFw0yMzAxMTIwODExNTZaFw0yNDAxMTIwODMxNTZaMBMxETAPBgNVBAMMCDIwMjMwMTEyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAseKf1weEacJ67D6/...laxQPUbuIL+DaXVkKRm1V3GgIpKTBqMzTf4tCpy7rpUZbhcwAFw6h9A==");
keyCredential.setKey(key);
keyCredential.setDisplayName("CN=20230112");
keyCredentials.add(keyCredential);
application.setKeyCredentials(keyCredentials);
Application result = graphClient.applications().byApplicationId("{application-id}").patch(application);
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.models.application import Application
from msgraph.generated.models.key_credential import KeyCredential
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = Application(
key_credentials = [
KeyCredential(
end_date_time = "2024-01-11T15:31:26Z",
start_date_time = "2023-01-12T15:31:26Z",
type = "AsymmetricX509Cert",
usage = "Verify",
key = base64.urlsafe_b64decode("base64MIIDADCCAeigAwIBAgIQP6HEGDdZ65xJTcK4dCBvZzANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAgyMDIzMDExMjAeFw0yMzAxMTIwODExNTZaFw0yNDAxMTIwODMxNTZaMBMxETAPBgNVBAMMCDIwMjMwMTEyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAseKf1weEacJ67D6/...laxQPUbuIL+DaXVkKRm1V3GgIpKTBqMzTf4tCpy7rpUZbhcwAFw6h9A=="),
display_name = "CN=20230112",
),
],
)
result = await graph_client.applications.by_application_id('application-id').patch(request_body)
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new Application
{
KeyCredentials = new List<KeyCredential>
{
new KeyCredential
{
EndDateTime = DateTimeOffset.Parse("2024-01-11T15:31:26Z"),
StartDateTime = DateTimeOffset.Parse("2023-01-12T09:31:26Z"),
Type = "AsymmetricX509Cert",
Usage = "Verify",
Key = Convert.FromBase64String("base64MIIDADCCAeigAwIBAgIQejfrj3S974xI//npv7hFHTANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAgyMDIzMDExNDAeFw0yMzAxMTIwOTA4NThaFw0yNDAxMTIwOTI4NThaMBMxETAPBgNVBAMMCDIwMjMwMTE0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt5vEj6j1l5wOVHR4eDGe77HWslaIVJ1NqxrXPm/...+R+U7sboj+kUvmFzXI+Ge73Liu8egL2NzOHHpO43calWgq36a9YW1yhBQR1ioEchu6jmudW3rF6ktmVqQ=="),
DisplayName = "CN=20230114",
},
new KeyCredential
{
CustomKeyIdentifier = Convert.FromBase64String("52ED9B5038A47B9E2E2190715CC238359D4F8F73"),
Type = "AsymmetricX509Cert",
Usage = "Verify",
Key = Convert.FromBase64String("base64MIIDADCCAeigAwIBAgIQfoIvchhpToxKEPI4iMrU1TANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAgyMDIzMDExMzAeFw0yMzAxMTIwODI3NTJaFw0yNDAxMTIwODQ3NTJaMBMxETAPBgNVBAMMCDIwMjMwMTEzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw+iqg1nMjYmFcFJh/.../S5X6qoEOyJBgtfpSBANWAdA=="),
DisplayName = "CN=20230113",
},
},
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Applications["{application-id}"].PatchAsync(requestBody);
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.models.application import Application
from msgraph.generated.models.key_credential import KeyCredential
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = Application(
key_credentials = [
KeyCredential(
end_date_time = "2024-01-11T15:31:26Z",
start_date_time = "2023-01-12T09:31:26Z",
type = "AsymmetricX509Cert",
usage = "Verify",
key = base64.urlsafe_b64decode("base64MIIDADCCAeigAwIBAgIQejfrj3S974xI//npv7hFHTANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAgyMDIzMDExNDAeFw0yMzAxMTIwOTA4NThaFw0yNDAxMTIwOTI4NThaMBMxETAPBgNVBAMMCDIwMjMwMTE0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt5vEj6j1l5wOVHR4eDGe77HWslaIVJ1NqxrXPm/...+R+U7sboj+kUvmFzXI+Ge73Liu8egL2NzOHHpO43calWgq36a9YW1yhBQR1ioEchu6jmudW3rF6ktmVqQ=="),
display_name = "CN=20230114",
),
KeyCredential(
custom_key_identifier = base64.urlsafe_b64decode("52ED9B5038A47B9E2E2190715CC238359D4F8F73"),
type = "AsymmetricX509Cert",
usage = "Verify",
key = base64.urlsafe_b64decode("base64MIIDADCCAeigAwIBAgIQfoIvchhpToxKEPI4iMrU1TANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAgyMDIzMDExMzAeFw0yMzAxMTIwODI3NTJaFw0yNDAxMTIwODQ3NTJaMBMxETAPBgNVBAMMCDIwMjMwMTEzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw+iqg1nMjYmFcFJh/.../S5X6qoEOyJBgtfpSBANWAdA=="),
display_name = "CN=20230113",
),
],
)
result = await graph_client.applications.by_application_id('application-id').patch(request_body)
Вы использовали Microsoft Graph для обновления учетных данных сертификата для объекта приложения. Этот процесс является программной альтернативой использованию Центр администрирования Microsoft Entra. Вы также можете обновить учетные данные сертификата для субъекта-службы, выполнив аналогичный процесс и вызвав конечную точку https://graph.microsoft.com/v1.0/servicePrincipals/ .