Применяется к:
Клиенты рабочей силы (дополнительные сведения)
Узнайте, как настроить код для управляющей программы, вызывающей веб-API.
Библиотеки Майкрософт, поддерживающие демон-приложения
Следующие библиотеки Майкрософт поддерживают демон-приложения:
1Универсальные условия лицензионного соглашения для веб-служб применяются к библиотекам в общедоступной предварительной версии.
Демо-н-программы используют разрешения приложений, а не делегированные разрешения. Поэтому поддерживаемый ими тип учетной записи не может быть учетной записью в любом каталоге организации или личной учетной записью Майкрософт (например, Skype, Xbox, Outlook.com). Не существует администратора арендатора, который мог бы предоставить согласие служебному приложению для личной учетной записи Microsoft. Вам нужно выбрать учетные записи в моей организации или учетных записях в любой организации.
Орган, указанный в конфигурации приложения, должен включать идентификатор арендатора или доменное имя, связанное с вашей организацией.
Даже если вы хотите предоставить мультитенантный инструмент, следует использовать идентификатор клиента или доменное имя, а неcommonorganizations с этим потоком данных, так как служба не может надежно определить, какой клиент следует использовать.
В библиотеках проверки подлинности Майкрософт (MSAL) учетные данные клиента (секрет или сертификат) передаются в качестве параметра конструкции конфиденциального клиентского приложения.
Внимание
Даже если приложение является консольным и работает как служба, то, если это управляющее приложение, оно должно быть конфиденциальным клиентским приложением.
Файл конфигурации
Файл конфигурации определяет:
- Облачный экземпляр и идентификатор клиента, которые вместе образуют авторитет.
- Идентификатор клиента, полученный при регистрации приложения.
- Секрет клиента или сертификат.
Ниже приведен пример определения конфигурации в файле appsettings.js. Этот пример взят из примера кода управляющей программы консоли .NET на 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]"
}
]
}
}
Вы предоставляете сертификат вместо секрета клиента или учетные данные федерации идентичности рабочих нагрузок.
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");
Параметры конфигурации для примера управляющей программы Node.js находятся в файле 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/
При создании конфиденциального клиента с секретами клиента файл конфигурации parameters.js в примере управляющей программы Python выглядит следующим образом:
{
"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"
}
При создании конфиденциального клиента с сертификатами файл конфигурации parameters.js в примере управляющей программы Python выглядит следующим образом:
{
"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"
}
Ниже приведен пример определения конфигурации в файле appsettings.js. Этот пример взят из примера кода управляющей программы консоли .NET на 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]"
}
Вы предоставляете ClientSecret либо CertificateName. Эти параметры являются эксклюзивными.
Создайте экземпляр приложения MSAL
Чтобы создать экземпляр приложения MSAL, добавьте, вызовите или импортируйте пакет MSAL (в зависимости от языка).
Конструкция отличается в зависимости от того, используете вы клиентские секреты или сертификаты (или, в качестве расширенного сценария, подписанные утверждения).
Укажите ссылку на пакет
Ссылка на пакет MSAL в коде приложения.
Добавьте в приложение пакет NuGet Microsoft.Identity.Web.TokenAcquisition.
Кроме того, если вы хотите вызвать Microsoft Graph, добавьте пакет Microsoft.Identity.Web.GraphServiceClient .
Проект может быть следующим образом. Файл appsettings.json необходимо скопировать в выходной каталог.
<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>
В файле Program.cs добавьте директиву using в код для ссылки на 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;
Установите пакеты, выполнив команду npm install в папке, в которой package.json находится файл. Затем импортируйте msal-node пакет:
const msal = require('@azure/msal-node');
import msal
import json
import sys
import logging
Добавьте в приложение пакет NuGet Microsoft.Identity.Client, а затем добавьте в код директиву using для ссылки на него.
В MSAL.NET конфиденциальное клиентское приложение представлено интерфейсом IConfidentialClientApplication.
using Microsoft.Identity.Client;
IConfidentialClientApplication app;
Создайте экземпляр конфиденциального клиентского приложения с клиентским секретом
Вот код для создания экземпляра конфиденциального клиентского приложения с секретом клиента:
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();
// ...
}
}
Конфигурация считывается из appsettings.json:
IClientCredential credential = ClientCredentialFactory.createFromSecret(CLIENT_SECRET);
ConfidentialClientApplication cca =
ConfidentialClientApplication
.builder(CLIENT_ID, credential)
.authority(AUTHORITY)
.build();
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
)
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
.WithClientSecret(config.ClientSecret)
.WithAuthority(new Uri(config.Authority))
.Build();
Authority — это объединение облачного экземпляра и идентификатора клиента, например https://login.microsoftonline.com/contoso.onmicrosoft.com или https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee. В файле appsettings.json, показанном в разделе "Файл конфигурации", экземпляр и клиент представлены значениями Instance и Tenant соответственно.
В образце кода, взятом из предыдущего фрагмента, Authority является свойством класса AuthenticationConfig и определяется следующим образом:
/// <summary>
/// URL of the authority
/// </summary>
public string Authority
{
get
{
return String.Format(CultureInfo.InvariantCulture, Instance, Tenant);
}
}
Создание экземпляра конфиденциального клиентского приложения с сертификатом клиента
Ниже приведен код для создания приложения с сертификатом.
Сам код точно такой же. Сертификат описан в конфигурации.
Существует множество способов получения сертификата. Дополнительные сведения см. в разделе https://aka.ms/ms-id-web-certificates.
Вот как вы будете делать, чтобы получить сертификат из KeyVault. Удостоверение Майкрософт передает управление DefaultAzureCredential из Azure Identity и использует управляемую идентичность, если она доступна, чтобы получить доступ к сертификату из Хранилища ключей. Вы можете отлаживать свое приложение локально, поскольку оно использует ваши учетные данные разработчика.
"ClientCredentials": [
{
"SourceType": "KeyVault",
"KeyVaultUrl": "https://yourKeyVaultUrl.vault.azure.net",
"KeyVaultCertificateName": "NameOfYourCertificate"
}
В MSAL Java для создания экземпляра конфиденциального клиентского приложения с сертификатами предусмотрено два построителя:
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();
или
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();
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);
Дополнительные сведения см. статье Использование учетных данных сертификата с 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
)
X509Certificate2 certificate = ReadCertificate(config.CertificateName);
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
.WithCertificate(certificate)
.WithAuthority(new Uri(config.Authority))
.Build();
Расширенный сценарий: создание экземпляра конфиденциального клиентского приложения с утверждениями клиента
Помимо использования секрета клиента или сертификата конфиденциальные клиентские приложения также могут подтвердить свою личность с помощью утверждений клиента. Дополнительные сведения см. в разделе CredentialDescription .
IClientCredential credential = ClientCredentialFactory.createFromClientAssertion(assertion);
ConfidentialClientApplication cca =
ConfidentialClientApplication
.builder(CLIENT_ID, credential)
.authority(AUTHORITY)
.build();
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);
Дополнительные сведения см. в статье Инициализация объекта ConfidentialClientApplication.
В MSAL Python можно предоставить клиентские заявки с помощью утверждений, которые будут подписаны этим закрытым ключом 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
)
Дополнительные сведения см. в справочной документации по Python MSAL для ConfidentialClientApplication.
Вместо секрета клиента или сертификата конфиденциальное клиентское приложение также может подтвердить свою подлинность с помощью утверждений клиента.
MSAL.NET имеет два метода для предоставления подписанных утверждений для конфиденциального клиентского приложения:
.WithClientAssertion()
.WithClientClaims()
При использовании WithClientAssertion предоставьте подписанный JWT. Этот расширенный сценарий подробно описан в разделе Утверждения клиента.
string signedClientAssertion = ComputeAssertion();
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
.WithClientAssertion(signedClientAssertion)
.Build();
При использовании WithClientClaimsMSAL.NET создает подписанное утверждение, содержащее утверждения, ожидаемые идентификатором Microsoft Entra, а также дополнительные утверждения клиента, которые нужно отправить.
В этом коде показано, как это сделать:
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();
Дополнительные сведения см. в разделе Утверждения клиента.
Следующие шаги