Microsoft Entra 확인된 ID에는 요청 서비스 REST API가 포함됩니다. 이 API를 사용하면 자격 증명을 발급하고 확인할 수 있습니다. 이 문서에서는 요청 서비스 REST API 사용을 시작하는 방법을 보여 줍니다.
API 액세스 토큰
애플리케이션이 요청 서비스 REST API에 액세스할 수 있도록 필요한 권한이 있는 유효한 액세스 토큰을 포함해야 합니다. Microsoft ID 플랫폼에서 발급한 액세스 토큰에는 요청 서비스 REST API가 호출자의 유효성을 검사하는 데 사용하는 정보(범위)가 포함됩니다. 액세스 토큰은 호출자가 요청하는 작업을 수행할 수 있는 적절한 권한을 갖도록 합니다.
액세스 토큰을 가져오려면 앱이 Microsoft ID 플랫폼에 등록되고 관리자가 요청 서비스 REST API에 대한 액세스 권한을 부여받아야 합니다. verifiable-credentials-app 애플리케이션을 등록하지 않은 경우 앱 등록한 다음 애플리케이션 비밀생성하는 참조하세요.
액세스 토큰 가져오기
OAuth 2.0 클라이언트 자격 증명 부여 흐름 사용하여 Microsoft ID 플랫폼을 사용하여 액세스 토큰을 획득합니다. 이 목적을 위해 신뢰할 수 있는 라이브러리를 사용합니다. 이 자습서에서는 Microsoft 인증 라이브러리 (MSAL)를 사용합니다. MSAL은 보안 웹 API를 호출할 수 있는 앱에 인증 및 권한 부여 추가를 간소화합니다.
POST /{tenant}/oauth2/v2.0/token HTTP/1.1 //Line breaks for clarity
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=3db474b9-6a0c-4840-96ac-1fceb342124f/.default
&client_secret=sampleCredentia1s
&grant_type=client_credentials
// Initialize MSAL library by using the following code
ConfidentialClientApplicationBuilder.Create(AppSettings.ClientId)
.WithClientSecret(AppSettings.ClientSecret)
.WithAuthority(new Uri(AppSettings.Authority))
.Build();
// Acquire an access token
result = await app.AcquireTokenForClient(AppSettings.Scopes)
.ExecuteAsync();
// Initialize MSAL library by using the following code
const msalConfig = {
auth: {
clientId: config.azClientId,
authority: `https://login.microsoftonline.com/${config.azTenantId}`,
clientSecret: config.azClientSecret,
},
system: {
loggerOptions: {
loggerCallback(loglevel, message, containsPii) {
console.log(message);
},
piiLoggingEnabled: false,
logLevel: msal.LogLevel.Verbose,
}
}
};
const cca = new msal.ConfidentialClientApplication(msalConfig);
const msalClientCredentialRequest = {
scopes: ["3db474b9-6a0c-4840-96ac-1fceb342124f/.default"],
skipCache: false,
};
module.exports.msalCca = cca;
module.exports.msalClientCredentialRequest = msalClientCredentialRequest;
// Acquire an access token
const result = await mainApp.msalCca.acquireTokenByClientCredential(mainApp.msalClientCredentialRequest);
if ( result ) {
accessToken = result.accessToken;
}
# Initialize MSAL library by using the following code
msalCca = msal.ConfidentialClientApplication( config["azClientId"],
authority="https://login.microsoftonline.com/" + config["azTenantId"],
client_credential=config["azClientSecret"],
)
# Acquire an access token
accessToken = ""
result = msalCca.acquire_token_for_client( scopes="3db474b9-6a0c-4840-96ac-1fceb342124f/.default" )
if "access_token" in result:
accessToken = result['access_token']
// Initialize MSAL library by using the following code
ConfidentialClientApplication app = ConfidentialClientApplication.builder(
clientId,
ClientCredentialFactory.createFromSecret(clientSecret))
.authority(authority)
.build();
// Acquire an access token
ClientCredentialParameters clientCredentialParam = ClientCredentialParameters.builder(
Collections.singleton(scope))
.build();
CompletableFuture<IAuthenticationResult> future = app.acquireToken(clientCredentialParam);
IAuthenticationResult result = future.get();
return result.accessToken();
앞의 코드에서 다음 매개 변수를 제공합니다.
매개 변수
조건
묘사
권위
필수
애플리케이션이 작동할 예정인 디렉터리 테넌트입니다. 예: https://login.microsoftonline.com/{your-tenant}. (your-tenant을(를) 테넌트 ID 또는 이름로 대체하십시오.)
클라이언트 ID
필수
앱에 할당된 애플리케이션 ID입니다. 이 정보는 앱을 등록한 Azure Portal에서 찾을 수 있습니다.
클라이언트 암호
필수
앱에 대해 생성한 클라이언트 암호입니다.
범위
필수
3db474b9-6a0c-4840-96ac-1fceb342124f/.default으로 설정해야 합니다. 이 설정은 역할의 클레임을 가진 VerifiableCredential.Create.All액세스 토큰을 생성합니다.
콘솔 앱의 ID를 사용하여 액세스 토큰을 가져오는 방법에 대한 자세한 내용은 다음 문서 중 하나를 참조하세요.
POST /{tenant}/oauth2/v2.0/token HTTP/1.1 //Line breaks for clarity
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=3db474b9-6a0c-4840-96ac-1fceb342124f/.default
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg
&grant_type=client_credentials
// Initialize MSAL library by using the following code
X509Certificate2 certificate = AppSettings.ReadCertificate(AppSettings.CertificateName);
app = ConfidentialClientApplicationBuilder.Create(AppSettings.ClientId)
.WithCertificate(certificate)
.WithAuthority(new Uri(AppSettings.Authority))
.Build();
// Acquire an access token
result = await app.AcquireTokenForClient(AppSettings.Scopes)
.ExecuteAsync();
// Initialize MSAL library by using the following code
const msalConfig = {
auth: {
clientId: config.azClientId,
authority: `https://login.microsoftonline.com/${config.azTenantId}`,
clientCertificate: {
thumbprint: "CERT_THUMBPRINT", // a 40-digit hexadecimal string
privateKey: "CERT_PRIVATE_KEY"
}
},
system: {
loggerOptions: {
loggerCallback(loglevel, message, containsPii) {
console.log(message);
},
piiLoggingEnabled: false,
logLevel: msal.LogLevel.Verbose,
}
}
};
const cca = new msal.ConfidentialClientApplication(msalConfig);
const msalClientCredentialRequest = {
scopes: ["3db474b9-6a0c-4840-96ac-1fceb342124f/.default"],
skipCache: false,
};
module.exports.msalCca = cca;
module.exports.msalClientCredentialRequest = msalClientCredentialRequest;
// Acquire an access token
const result = await mainApp.msalCca.acquireTokenByClientCredential(mainApp.msalClientCredentialRequest);
if ( result ) {
accessToken = result.accessToken;
}
# Initialize MSAL library by using the following code
with open(config["azCertificatePrivateKeyLocation"], "rb") as file:
private_key = file.read()
with open(config["azCertificateLocation"]) as file:
public_certificate = file.read()
cert = load_pem_x509_certificate(data=bytes(public_certificate, 'UTF-8'), backend=default_backend())
thumbprint = (cert.fingerprint(hashes.SHA1()).hex())
msalCca = msal.ConfidentialClientApplication( config["azClientId"],
authority="https://login.microsoftonline.com/" + config["azTenantId"],
client_credential={
"private_key": private_key,
"thumbprint": thumbprint,
"public_certificate": public_certificate
}
)
# Acquire an access token
accessToken = ""
result = msalCca.acquire_token_for_client( scopes="3db474b9-6a0c-4840-96ac-1fceb342124f/.default" )
if "access_token" in result:
accessToken = result['access_token']
// Initialize MSAL library by using the following code
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Files.readAllBytes(Paths.get(certKeyLocation)));
PrivateKey key = KeyFactory.getInstance("RSA").generatePrivate(spec);
java.io.InputStream certStream = (java.io.InputStream)new ByteArrayInputStream(Files.readAllBytes(Paths.get(certLocation)));
X509Certificate cert = (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(certStream);
ConfidentialClientApplication app = ConfidentialClientApplication.builder(
clientId,
ClientCredentialFactory.createFromCertificate(key, cert))
.authority(authority)
.build();
// Acquire an access token
ClientCredentialParameters clientCredentialParam = ClientCredentialParameters.builder(
Collections.singleton(scope))
.build();
CompletableFuture<IAuthenticationResult> future = app.acquireToken(clientCredentialParam);
IAuthenticationResult result = future.get();
return result.accessToken();
API 호출
확인 가능한 자격 증명을 발급하거나 확인하려면 다음을 수행합니다.
요청 서비스 REST API에 대한 HTTP POST 요청을 생성합니다. 테넌트 ID는 액세스 토큰에 클레임으로 존재하기 때문에 URL에 더 이상 필요하지 않습니다.
문제
POST https://verifiedid.did.msidentity.com/v1.0/verifiableCredentials/createIssuanceRequest
을 확인하십시오
POST https://verifiedid.did.msidentity.com/v1.0/verifiableCredentials/createPresentationRequest
요청 페이로드에는 발급 및 프레젠테이션 콜백 엔드포인트가 포함됩니다. 엔드포인트는 웹 애플리케이션의 일부이며 HTTPS 프로토콜을 통해 공개적으로 사용할 수 있어야 합니다. 요청 서비스 API는 엔드포인트를 호출하여 특정 이벤트에 대해 앱에 알릴 수 있습니다. 예를 들어 사용자가 QR 코드를 스캔하거나, 인증자 앱에 대한 딥 링크를 사용하거나, 프레젠테이션 프로세스를 완료할 때 이러한 이벤트가 발생할 수 있습니다.
다음 도표는 앱이 Request Service REST API에 호출하는 과정과 애플리케이션으로의 콜백을 설명합니다.
API 및 콜백 이벤트에 대한 호출을 보여 주는
들어오는 HTTP POST 요청을 수신 대기하도록 엔드포인트를 구성합니다. 다음 코드 조각은 발급 콜백 HTTP 요청을 처리하는 방법과 그에 따라 UI를 업데이트하는 방법을 보여 줍니다.
[HttpPost]
public async Task<ActionResult> IssuanceCallback()
{
try
{
string content = new System.IO.StreamReader(this.Request.Body).ReadToEndAsync().Result;
_log.LogTrace("callback!: " + content);
JObject issuanceResponse = JObject.Parse(content);
// More code here
if (issuanceResponse["code"].ToString() == "request_retrieved")
{
var cacheData = new
{
status = "request_retrieved",
message = "QR Code is scanned. Waiting for issuance...",
};
_cache.Set(state, JsonConvert.SerializeObject(cacheData));
// More code here
}
}