L’ID vérifié Microsoft Entra inclut l’API REST du service de requête. Cette API vous permet de émettre et de vérifier les informations d’identification. Cet article explique comment commencer à utiliser l’API REST du service de requête.
Jeton d’accès à l’API
Votre application doit inclure un jeton d’accès valide avec les autorisations requises afin qu’elle puisse accéder à l’API REST du service de requête. Les jetons d’accès émis par la plateforme d’identités Microsoft contiennent des informations (autorisations) que l’API REST de Request Service utilise pour valider la requête de l’appelant. Un jeton d’accès garantit que l’appelant dispose des autorisations appropriées pour effectuer l’opération qu’il demande.
Pour obtenir un jeton d’accès, votre application doit être inscrite auprès de la plateforme d’identités Microsoft et être autorisée par un administrateur pour accéder à l’API REST du service de requête. Si vous n’avez pas inscrit l’application verifiable-credentials-app, consultez comment inscrire l’application puis générer un secret d’application.
Obtenir un jeton d’accès
Utilisez le flux d’octroi des informations d'identification du client OAuth 2.0 pour acquérir le jeton d’accès à l’aide de la plateforme d'identités Microsoft. Utilisez une bibliothèque approuvée à cet effet. Dans ce tutoriel, nous utilisons la bibliothèque d’authentification Microsoft (MSAL). MSAL simplifie l’ajout d’authentification et d’autorisation à une application qui peut appeler une API web sécurisée.
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();
Dans le code précédent, fournissez les paramètres suivants :
Paramètre
Condition
Description
Autorité
Obligatoire
Le locataire de l’annuaire sur lequel les plans d’application opèrent. Par exemple : https://login.microsoftonline.com/{your-tenant}. (Remplacez your-tenant par votre ID de locataire ou le nom.)
ID client
Obligatoire
ID d’application affecté à votre application. Vous trouverez ces informations dans le portail Azure, où vous avez inscrit votre application.
Clé secrète client
Obligatoire
Clé secrète client que vous avez générée pour votre application.
Étendues
Obligatoire
Cette propriété doit être définie sur 3db474b9-6a0c-4840-96ac-1fceb342124f/.default. Ce paramètre génère un jeton d’accès avec une revendication de rôle de VerifiableCredential.Create.All.
Pour plus d’informations sur l’obtention d’un jeton d’accès à l’aide de l’identité d’une application console, consultez l’un des articles suivants :
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();
Appeler l’API
Pour émettre ou vérifier les justificatifs vérifiables :
Créez une requête HTTP POST sur l’API REST du service de requête. L’ID de locataire n’est plus nécessaire dans l’URL, car il est présent sous la forme d’une revendication dans le jeton d’accès.
Problème
POST https://verifiedid.did.msidentity.com/v1.0/verifiableCredentials/createIssuanceRequest
Vérifier
POST https://verifiedid.did.msidentity.com/v1.0/verifiableCredentials/createPresentationRequest
Attachez le jeton d’accès en tant que jeton du porteur à l’en-tête d’autorisation dans une requête HTTP.
Authorization: Bearer <token>
Attribuez à l’en-tête Content-Type la valeur Application/json.
Préparez et attachez la charge utile de requête Émissionou Présentation au corps de la demande.
Envoyez la demande à l’API REST du service de requête.
L’API de service de requête retourne un code d’état HTTP 201 Created lors d’un appel réussi. Si l’appel d’API retourne une erreur, consultez la documentation de référence des erreurs .
Demande de présentation avec FaceCheck. Lorsque vous utilisez FaceCheck, la includeReceipt doit être false, car la réception n’est pas prise en charge.
La charge utile de la demande contient le point de terminaison de rappel d’émission et de présentation. Le point de terminaison fait partie de votre application web et doit être disponible publiquement via le protocole HTTPS. L’API Request Service appelle votre point de terminaison pour informer votre application sur certains événements. Par exemple, de tels événements peuvent être lorsqu’un utilisateur analyse le code QR, utilise le lien profond vers l’application d’authentificateur ou termine le processus de présentation.
Le diagramme suivant décrit l’appel que votre application effectue à l’API REST du service de requête et les rappels à votre application.
Configurez votre point de terminaison pour écouter les requêtes HTTP POST entrantes. L’extrait de code suivant montre comment gérer la requête HTTP de rappel d’émission et comment mettre à jour l’interface utilisateur en conséquence :
Sans objet. Choisissez l’un des autres langages de programmation.
[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
}
}
Pour le code complet, consultez le code d'émission et de présentation sur le dépôt GitHub.
mainApp.app.post('/api/issuer/issuance-request-callback', parser, async (req, res) => {
var body = '';
req.on('data', function (data) {
body += data;
});
req.on('end', function () {
requestTrace( req );
console.log( body );
var issuanceResponse = JSON.parse(body.toString());
var message = null;
if ( issuanceResponse.code == "request_retrieved" ) {
message = "QR Code is scanned. Waiting for issuance to complete...";
}
if ( issuanceResponse.code == "issuance_successful" ) {
message = "Credential successfully issued";
}
if ( issuanceResponse.code == "issuance_error" ) {
message = issuanceResponse.error.message;
}
// More code here
res.send()
});
res.send()
})