A ID Verificada do Microsoft Entra inclui a API REST do Serviço de Solicitação. Essa API permite que você emita e verifique credenciais. Este artigo mostra como começar a usar a API REST do Serviço de Solicitação.
Token de acesso à API
Seu aplicativo precisa incluir um token de acesso válido com as permissões necessárias para que possa acessar a API REST do Serviço de Solicitação. Os tokens de acesso emitidos pela plataforma de identidade da Microsoft contêm informações (escopos) que a API REST do Serviço de Solicitação usa para validar o chamador. Um token de acesso garante que o chamador tenha as permissões adequadas para executar a operação que está solicitando.
Para obter um token de acesso, seu aplicativo deve ser registrado na plataforma de identidade da Microsoft e ser autorizado por um administrador para acessar a API REST do Serviço de Solicitação. Se não registou a aplicação de credenciais verificáveis, consulte como registar a aplicação e, em seguida, gerar uma chave secreta da aplicação.
Obter um token de acesso
Use o fluxo de concessão de credenciais do cliente OAuth 2.0 para adquirir o token de acesso usando a plataforma de identidade da Microsoft. Use uma biblioteca confiável para essa finalidade. Neste tutorial, usamos a Biblioteca de Autenticação da Microsoft (MSAL). O MSAL simplifica a adição de autenticação e autorização a um aplicativo que pode chamar uma API da Web segura.
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();
No código anterior, forneça os seguintes parâmetros:
Parâmetro
Condição
Descrição
Autoridade
Necessário
O locatário do diretório contra o qual o aplicativo planeja operar. Por exemplo: https://login.microsoftonline.com/{your-tenant}. (Substitua your-tenant pelo seu ID de inquilino ou nome.)
ID do Cliente
Necessário
A ID do aplicativo atribuída ao seu aplicativo. Você pode encontrar essas informações no portal do Azure, onde registrou seu aplicativo.
Segredo do cliente
Necessário
O segredo do cliente que geraste para a tua aplicação.
Âmbitos de aplicação
Necessário
Deve ser definido como 3db474b9-6a0c-4840-96ac-1fceb342124f/.default. Essa configuração produz um token de acesso com um funções declaração de VerifiableCredential.Create.All.
Para obter mais informações sobre como obter um token de acesso usando a identidade de um aplicativo de console, consulte um dos seguintes artigos:
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();
Chamar a API
Para emitir ou verificar uma credencial verificável:
Construa uma solicitação HTTP POST para a API REST do Serviço de Solicitação. O ID do locatário não é mais necessário na URL porque está presente como uma declaração no token de acesso.
Questão
POST https://verifiedid.did.msidentity.com/v1.0/verifiableCredentials/createIssuanceRequest
Verificar
POST https://verifiedid.did.msidentity.com/v1.0/verifiableCredentials/createPresentationRequest
Anexe o token de acesso como um token de portador ao cabeçalho de autorização em uma solicitação HTTP.
Authorization: Bearer <token>
Defina o cabeçalho Content-Type como Application/json.
Prepare e anexe a carga útil de emissão ou apresentação ao corpo do pedido.
Envie a solicitação para a API REST do Serviço de Solicitação.
A API do Serviço de Solicitação retorna um código de status HTTP 201 Created em uma chamada bem-sucedida. Se a chamada de API retornar um erro, verifique a documentação de referência de erro .
Exemplo de solicitação de emissão
O exemplo a seguir demonstra uma solicitação de emissão de credenciais verificável. Para obter informações sobre a carga útil, consulte a especificação de emissão do Request Service REST API.
POST https://verifiedid.did.msidentity.com/v1.0/verifiableCredentials/createIssuanceRequest
Content-Type: application/json
Authorization: Bearer <token>
{...JSON payload...}
A carga útil da solicitação contém o ponto de extremidade de retorno de chamada de emissão e apresentação . O endpoint faz parte da sua aplicação web e deve estar disponível de forma pública através do protocolo HTTPS. A API de Pedido chama o seu endpoint para informar a sua aplicação sobre determinados eventos. Por exemplo, esses eventos podem ser quando um usuário escaneia o código QR, usa o link direto para o aplicativo autenticador ou conclui o processo de apresentação.
O diagrama a seguir descreve a chamada que a sua aplicação faz para a API REST do Serviço de Pedido e os retornos de chamada para a sua aplicação.
Configure o seu endpoint para escutar solicitações HTTP POST recebidas. O seguinte trecho de código demonstra como lidar com o pedido HTTP de resposta de emissão e como atualizar a IU de acordo:
Não aplicável. Escolha uma das outras linguagens de programação.
[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
}
}
Para obter o código completo, consulte o de emissão de e apresentação código no repositório 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()
})