Web API を呼び出すデーモン アプリケーションのコードを構成する方法について説明します。
デーモン アプリをサポートしている Microsoft ライブラリ
次の Microsoft ライブラリはデーモン アプリをサポートしています。
1 オンライン サービスのユニバーサル ライセンス条項は、"パブリック プレビュー" のライブラリに適用されます。
デーモン アプリケーションでは、委任されたアクセス許可ではなく、アプリケーションのアクセス許可が使用されます。 そのため、サポートされているアカウントの種類を、組織のディレクトリ内のアカウントまたは個人用 Microsoft アカウント (例: Skype、Xbox、Outlook.com) にすることはできません。 Microsoft の個人アカウントの場合、デーモン アプリケーションに同意を付与するテナント管理者はいません。 "自分の所属組織のアカウント" または "任意の組織のアカウント" を選択する必要があります。
アプリケーション構成に指定された機関は、(組織に関連付けられたテナント ID またはドメイン名を指定して) テナント化する必要があります。
マルチテナント ツールを提供する場合でも、どのテナントを使用する必要があるかをサービスで確実に推測できないため、テナント ID またはドメイン名を使用する必要があります。このフローでは common
や organizations
は使用しません。
MSAL ライブラリでは、クライアントの資格情報 (シークレットまたは証明書) は、機密クライアント アプリケーション構築のパラメーターとして渡されます。
重要
アプリケーションが、サービスとして実行されているコンソール アプリケーションであっても、それがデーモン アプリケーションの場合は、機密クライアント アプリケーションである必要があります。
構成ファイル
構成ファイルでは、以下を定義します。
- 機関を構成するクラウド インスタンスとテナント ID。
- アプリケーションの登録から返されたクライアント ID。
- クライアント シークレットまたは証明書のいずれか。
appsettings.json ファイル内で構成を定義する例を次に示します。 この例は、GitHub の .NET コンソール デーモンのコード サンプルから引用しています。
{
"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]"
}
]
}
}
クライアント シークレットではなく証明書、またはワークロード ID フェデレーション資格情報を指定します。
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/
クライアント シークレットを使用して機密クライアントをビルドしているとき、Python デーモン サンプルの parameters.json 構成ファイルは次のようになります。
{
"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"
}
証明書を使用して機密クライアントをビルドしているとき、Python デーモン サンプルの parameters.json 構成ファイルは次のようになります。
{
"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.json ファイル内で構成を定義する例を次に示します。 この例は、GitHub の .NET コンソール デーモンのコード サンプルから引用しています。
{
"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 パッケージを参照します。
Microsoft.Identity.Web.TokenAcquisition NuGet パッケージをアプリケーションに追加します。
または、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 ファイルで、Microsoft.Identity.Web を参照する using
ディレクティブをコードに追加します。
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
Microsoft.Identity.Client NuGet パッケージをアプリケーションに追加し、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
は、クラウド インスタンスとテナント ID (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 から証明書を取得する方法を次に示します。 Microsoft ID から Azure Identity の DefaultAzureCredential に委任し、KeyVault から証明書にアクセスできる場合はマネージド ID を使用します。 アプリケーションはローカルでそのままデバッグできます。その後、開発者の資格情報を使用します。
"ClientCredentials": [
{
"SourceType": "KeyVault",
"KeyVaultUrl": "https://yourKeyVaultUrl.vault.azure.net",
"KeyVaultCertificateName": "NameOfYourCertificate"
}
MSAL Java では、証明書を使用して機密クライアント アプリケーションをインスタンス化するには、次の 2 つのビルダーがあります。
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 ノードでの証明書資格情報の使用に関するページを参照してください。
# 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();
高度なシナリオ: クライアント アサーションを使用して機密クライアント アプリケーションをインスタンス化する
機密クライアント アプリケーションでは、クライアント シークレットや証明書に加えて、クライアント アサーションを使用して ID を証明することもできます。 詳細については、「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
)
詳細については、ConfidentialClientApplication に関する MSAL Python のリファレンス ドキュメントを参照してください。
機密クライアント アプリケーションでは、クライアント シークレットまたは証明書ではなく、クライアント アサーションを使用してその ID を証明することもできます。
MSAL.NET には、機密クライアント アプリに署名付きアサーションを提供する方法が 2 つあります。
.WithClientAssertion()
.WithClientClaims()
WithClientAssertion
を使用する場合は、署名付き JWT を提供します。 この高度なシナリオの詳細については、クライアント アサーションに関する記事を参照してください。
string signedClientAssertion = ComputeAssertion();
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
.WithClientAssertion(signedClientAssertion)
.Build();
WithClientClaims
を使用する場合は、Microsoft Entra ID で想定される要求と、送信する追加のクライアント要求を含む署名付きアサーションが、MSAL.NET によって生成されます。
次のコードでは、それを行う方法を示します。
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();
ここでも、詳細については、クライアント アサーションに関するページを参照してください。
次のステップ