Vérification d’identité Microsoft Entra inclut l’API REST du service de requête. Cette API vous permet d’émettre et de vérifier des informations d’identification. Cet article vous montre comment commencer à utiliser l’API REST du service de demande.
Jeton d’accès API
Votre application doit inclure un jeton d’accès valide avec les autorisations requises pour pouvoir accéder à l’API REST du service de demande. Les jetons d’accès émis par la plateforme d’identité Microsoft contiennent des informations (étendues) que l’API REST du service de demande utilise pour valider l’appelant. Un jeton d’accès assure que l’appelant dispose des autorisations nécessaires pour effectuer l’opération qu’il demande.
Pour obtenir un jeton d’accès, votre application doit être enregistrée sur la plateforme d’identité Microsoft et être autorisée par un administrateur à accéder à l’API REST du service de demande. Si vous n’avez pas inscrit l’application verifiable-credentials-app, consultez comment inscrire l’application puis générer un secret d’application.
Obtention d’un jeton d’accès
Utilisez le workflow d’octroi d’informations d’identification du client OAuth 2.0 pour obtenir le jeton d’accès à l’aide du 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 de l’authentification et de l’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
Authority
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 ou nom de locataire.)
ID client
Obligatoire
Copiez l’ID d’application affecté à votre application. Ces informations sont disponibles dans le portail Azure où vous avez inscrit votre application.
Clé secrète client
Obligatoire
La 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 produit un jeton d’accès avec une revendication de rôles de VerifiableCredential.Create.All.
Pour plus d’informations sur la façon d’obtenir un jeton d’accès à l’aide de l’identité d’une application de 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 des justificatifs vérifiables :
Construisez une requête HTTP POST adressée à l’API REST du service de demande. 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 comme 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 demande Émissionou Présentation au corps de la demande.
Envoyez la demande à l’API REST du service de demande.
L’API du 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. Lors de l’utilisation de FaceCheck, la valeur 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 publiquement disponible par le biais du protocole HTTPS. L’API du service de requête appelle votre point de terminaison pour informer votre application lors de certains événements. Par exemple, lorsqu’un utilisateur scanne le code QR, utilise le lien ciblé avec son application d’authentification, ou termine le processus de présentation.
Le diagramme suivant décrit l’appel que votre application fait à l’API REST du service de demande, 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 traiter la demande HTTP de rappel d’émission et mettre à jour l’interface utilisateur en conséquence :
Non applicable. 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 obtenir le code complet, consultez le code d’émission et de présentation sur le référentiel 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()
})