Microsoft Entra Verified ID zawiera interfejs API REST usługi Request Service. Ten interfejs API umożliwia wystawianie i weryfikowanie poświadczeń. W tym artykule pokazano, jak rozpocząć korzystanie z interfejsu API REST usługi żądań.
Token dostępu interfejsu API
Aplikacja musi dołączyć prawidłowy token dostępu z wymaganymi uprawnieniami, aby mogła uzyskać dostęp do interfejsu API REST usługi żądań. Tokeny dostępu wystawione przez platformę tożsamości firmy Microsoft zawierają informacje (zakresy), których używa interfejs API REST usługi żądań do sprawdzania poprawności elementu wywołującego. Token dostępu gwarantuje, że obiekt wywołujący ma odpowiednie uprawnienia do wykonania żądanej operacji.
Aby uzyskać token dostępu, aplikacja musi zostać zarejestrowana na platformie tożsamości firmy Microsoft i autoryzowana przez administratora w celu uzyskania dostępu do interfejsu API REST usługi żądań. Jeśli nie zarejestrowano aplikacji aplikacji do weryfikacji poświadczeń, zobacz jak zarejestrować aplikację, a następnie wygenerować klucz tajny aplikacji.
Uzyskiwanie tokenu dostępu
Użyj przepływu uprawnień klienta OAuth 2.0 , aby uzyskać token dostępu przy użyciu platformy tożsamości Microsoft. W tym celu użyj zaufanej biblioteki. W tym samouczku użyjemy biblioteki Microsoft Authentication Library (MSAL). Biblioteka MSAL upraszcza dodawanie uwierzytelniania i autoryzacji do aplikacji, która może wywoływać bezpieczny internetowy interfejs 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();
W poprzednim kodzie podaj następujące parametry:
Parametr
Warunek
Opis
Autorytet
Wymagane
Dzierżawca katalogu, na którym aplikacja planuje działać. Na przykład: https://login.microsoftonline.com/{your-tenant}. (Zastąp your-tenant identyfikatorem dzierżawy lub nazwą).
Identyfikator klienta
Wymagane
Identyfikator aplikacji przypisany do aplikacji. Te informacje można znaleźć w witrynie Azure Portal, w której zarejestrowano aplikację.
Klucz tajny klienta
Wymagane
Tajny klucz klienta, który wygenerowałeś dla swojej aplikacji.
Zakresy
Wymagane
Musi być ustawione na 3db474b9-6a0c-4840-96ac-1fceb342124f/.default. To ustawienie tworzy token dostępu z roszczeniem roli typu równego VerifiableCredential.Create.All.
Aby uzyskać więcej informacji na temat uzyskiwania tokenu dostępu przy użyciu tożsamości aplikacji konsolowej, zobacz jeden z następujących artykułów:
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();
Wywoływanie interfejsu API
Aby wydać lub zweryfikować poświadczenia weryfikowalne:
Skonstruuj żądanie HTTP POST do Request Service REST API. Identyfikator dzierżawy nie jest już potrzebny w adresie URL, ponieważ jest obecny jako oświadczenie w tokenie dostępu.
Problem
POST https://verifiedid.did.msidentity.com/v1.0/verifiableCredentials/createIssuanceRequest
Zweryfikuj
POST https://verifiedid.did.msidentity.com/v1.0/verifiableCredentials/createPresentationRequest
Dołącz token dostępu jako token uwierzytelniający typu Bearer do nagłówka autoryzacji w żądaniu HTTP.
Authorization: Bearer <token>
Ustaw nagłówek Content-Type na wartość Application/json.
Przygotuj i dołącz wystawiania lub prezentacji ładunku żądania do treści żądania.
Wyślij żądanie do interfejsu API REST usługi Request Service.
Interfejs API dla żądań zwraca kod stanu HTTP 201 Created przy pomyślnym wywołaniu. Jeśli wywołanie interfejsu API zwróci błąd, zapoznaj się z dokumentacją referencyjną błędu.
W poniższym przykładzie pokazano weryfikowalne żądanie prezentacji poświadczeń. Aby uzyskać informacje o ładunku, zobacz specyfikację prezentacji interfejsu API REST usługi Request Service.
POST https://verifiedid.did.msidentity.com/v1.0/verifiableCredentials/createPresentationRequest
Content-Type: application/json
Authorization: Bearer <token>
{...JSON payload...}
Żądanie prezentacji z FaceCheck. W przypadku korzystania z funkcji FaceCheck includeReceipt musi być fałszywe, ponieważ potwierdzenie nie jest wtedy obsługiwane.
Ładunek żądania zawiera wystawianie oraz prezentację i wywołanie zwrotne punktu końcowego. Punkt końcowy jest częścią aplikacji internetowej i powinien być publicznie dostępny za pośrednictwem protokołu HTTPS. Interfejs API usługi Request Service wywołuje punkt końcowy, aby poinformować aplikację o niektórych zdarzeniach. Na przykład takie zdarzenia mogą występować, gdy użytkownik skanuje kod QR, używa linku głębokiego do aplikacji authenticator lub kończy proces prezentacji.
Na poniższym diagramie opisano wywołanie aplikacji wykonywane do interfejsu API REST usługi żądań oraz wywołania zwrotne do aplikacji.
Skonfiguruj punkt końcowy do nasłuchiwania przychodzących żądań HTTP POST. Poniższy fragment kodu pokazuje, jak obsługiwać żądanie HTTP dotyczące wywołania zwrotnego wydawania i jak odpowiednio zaktualizować interfejs użytkownika.
Nie dotyczy. Wybierz jeden z innych języków programowania.
[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
}
}
Aby uzyskać pełny kod, zobacz kod wystawienia i kod prezentacji w repozytorium 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()
})