적용:
직원 테넌트
외부 테넌트(자세히 알아보기)
웹 API를 호출하는 디먼 애플리케이션에 대한 코드를 구성하는 방법을 알아봅니다.
디먼 앱을 지원하는 Microsoft 라이브러리
다음 Microsoft 라이브러리는 디먼 앱을 지원합니다.
1온라인 서비스에 대한 유니버설 사용 조건은 공개 미리 보기의 라이브러리에 적용됩니다.
디먼 애플리케이션은 위임된 권한 대신 애플리케이션 권한을 사용합니다. 따라서 지원되는 계정 유형은 조직 디렉터리 또는 개인 Microsoft 계정(예: Skype, Xbox, Outlook.com)의 계정이 될 수 없습니다. Microsoft 개인 계정의 디먼 애플리케이션에 대한 동의 권한을 부여하는 테넌트 관리자가 없습니다.
내 조직의 계정 또는 모든 조직의 계정을 선택해야 합니다.
애플리케이션 구성에 지정된 기관에는 ypur 테넌트 ID 또는 조직과 연결된 도메인 이름이 포함되어야 합니다.
다중 테넌트 도구를 제공하려는 경우에도 서비스가 사용해야 하는 테넌트를 안정적으로 유추할 수 없으므로 이 흐름이 아닌사용해야 합니다.
MSAL(Microsoft 인증 라이브러리)에서 클라이언트 자격 증명(비밀 또는 인증서)은 기밀 클라이언트 애플리케이션 생성의 매개 변수로 전달됩니다.
중요
애플리케이션이 서비스로 실행되는 콘솔 애플리케이션이더라도 디먼 애플리케이션의 경우에는 기밀 클라이언트 애플리케이션이어야 합니다.
구성 파일
구성 파일은 다음을 정의합니다.
- 클라우드 인스턴스 및 테넌트 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 ID의 DefaultAzureCredential에 위임하고 KeyVault에서 인증서에 액세스할 수 있는 경우 관리 ID를 사용했습니다. 애플리케이션은 개발자 자격 증명을 사용하므로 로컬로 디버그할 수 있습니다.
"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 노드에서 인증서 자격 증명 사용을 참조하세요.
# 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에는 기밀 클라이언트 앱에 서명된 어설션을 제공하는 두 가지 방법이 있습니다.
.WithClientAssertion()
.WithClientClaims()
WithClientAssertion
을 사용하는 경우 서명된 JWT를 제공합니다. 이 고급 시나리오는 클라이언트 어설션에 자세히 설명되어 있습니다.
string signedClientAssertion = ComputeAssertion();
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
.WithClientAssertion(signedClientAssertion)
.Build();
WithClientClaims
를 사용하는 경우 MSAL.NET은 Microsoft Entra ID에서 예상한 클레임과 전송하려는 추가 클라이언트 클레임을 포함하는 서명된 어설션을 생성합니다.
이 코드가 해당 작업의 작동 방식을 보여 줍니다.
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();
자세한 내용은 클라이언트 어설션을 참조하세요.
다음 단계