Pular para o conteúdo principal

Primeiros passos

Esta página vai da chave de API até um hash assinado: instale um cliente, crie uma sessão, envie o usuário a um provedor e use a sessão que volta. Cada passo tem código em C#, PHP, Python, Node.js e Java. Como funciona explica o fluxo por trás dos passos.

O código assina um hash calculado pela sua biblioteca de assinatura. Assinando um PDF e Autenticação mostram handlers completos, que calculam esse hash e finalizam a assinatura com PKI SDK, Rest PKI ou PKI Express.

1. Obter uma chave de API​

Peça ao suporte da Lacuna Software (suporte@lacunasoftware.com) uma chave de API do CloudHub e informe as URIs de redirecionamento que a sua aplicação vai usar, em produção e em desenvolvimento. Se você for acrescentar os seus próprios parâmetros à URI de redirecionamento, como os exemplos abaixo fazem com fileId, peça uma entrada de host, como https://app.example.com, em vez de uma URI exata. Veja URIs de redirecionamento.

Os exemplos leem a chave da variável de ambiente CLOUDHUB_API_KEY. Mantenha-a no servidor.

2. Instalar um cliente​

dotnet add package Lacuna.Cloudhub.Client

Para a injeção de dependência do ASP.NET Core, adicione também o Lacuna.Cloudhub.ClientCore.

3. Criar um cliente​

using Lacuna.Cloudhub.Api;
using Lacuna.Cloudhub.Client;

var cloudhub = new CloudhubClient(
"https://cloudhub.lacunasoftware.com/",
Environment.GetEnvironmentVariable("CLOUDHUB_API_KEY"));

Com o Lacuna.Cloudhub.ClientCore, registre o cliente uma vez e injete ICloudhubService, que tem os mesmos métodos:

Program.cs
using Lacuna.Cloudhub.ClientCore;

builder.Services.AddCloudhub().Configure(builder.Configuration.GetSection("Cloudhub"));
appsettings.json
{
"Cloudhub": {
"Endpoint": "https://cloudhub.lacunasoftware.com/",
"ApiKey": "set it in user secrets or an environment variable"
}
}

4. Criar uma sessão​

Envie o CPF do signatário, só com os dígitos, e a URI para onde o CloudHub deve devolver o usuário. Os exemplos levam o ID do arquivo a assinar na URI de redirecionamento, para que a requisição que volta saiba de qual arquivo se trata.

var session = await cloudhub.CreateSessionAsync(new SessionCreateRequest {
Identifier = "12345678909",
RedirectUri = "https://app.example.com/sign/complete?fileId=42",
Type = TrustServiceSessionTypes.SingleSignature,
LifetimeInSeconds = 300,
});

foreach (var service in session.Services) {
Console.WriteLine($"{service.ServiceInfo.Provider}: {service.AuthUrl}");
}

Uma lista vazia significa que nenhum provedor tem um certificado para esse CPF. Informe o usuário e ofereça a opção de tentar outro CPF.

5. Enviar o usuário a um provedor​

Mostre uma opção para cada entrada e leve o navegador para a authUrl que o usuário escolher. badgeUrl é o logotipo do provedor e pode ser nula.

<!-- One link per entry of "services" -->
<a href="https://api.birdid.com.br/oauth/authorize?client_id=…">
<img src="https://cdn.lacunasoftware.com/img/psc/birdid.png" alt="BirdID" height="48">
Sign with SOLUTI
</a>

O usuário entra no provedor e aprova. O provedor devolve o navegador ao CloudHub, e o CloudHub o envia à sua URI de redirecionamento.

6. Ler o certificado quando o usuário voltar​

A sua URI de redirecionamento recebe o parâmetro session ao lado dos seus. Quando session não vem, o usuário não autorizou: leve-o de volta para escolher de novo.

// ASP.NET Core: GET /sign/complete?fileId=42&session=…
public async Task<IActionResult> Complete(string fileId, string session) {
if (string.IsNullOrEmpty(session)) {
return RedirectToAction("Index", new { fileId });
}

byte[] certificate = await cloudhub.GetCertificateAsync(session);
// ...
}

Antes de assinar, confira se o certificado pertence à pessoa esperada: compare o CPF dele com o que você enviou. Os exemplos completos fazem isso com a biblioteca de assinatura.

7. Assinar um hash​

A sua biblioteca de assinatura fornece o hash a assinar e o algoritmo de hash dele. Envie os dois com a sessão; o resultado é o valor da assinatura, que a biblioteca insere no documento. Identifique o algoritmo pelo OID (digestAlgorithmOid), como as bibliotecas de assinatura o informam, ou pelo nome (digestAlgorithm, como SHA-256).

byte[] signature = await cloudhub.SignHashAsync(new SignHashRequest {
Session = session,
Hash = toSignHash, // the hash, as bytes
DigestAlgorithmOid = digestAlgorithmOid,
});

8. Tratar erros​

O CloudHub informa um problema na sua requisição com HTTP 422 e um corpo JSON com code, message e, às vezes, details. O código mais comum é SessionExpired: a sessão expirou antes de ser usada, então envie o usuário ao provedor de novo. A página API REST lista todos os códigos.

try {
var signature = await cloudhub.SignHashAsync(request);
} catch (CloudhubApiException ex) when (ex.CodeStr == "SessionExpired") {
// Create a new session and send the user to the provider again
}

Compare CodeStr. A propriedade Code, do tipo enum, não é preenchida a partir da resposta.

Uma requisição sem uma chave de API válida recebe HTTP 401. Uma falha inesperada, como um provedor fora do ar, recebe HTTP 500 com um código curto no corpo; informe-o ao falar com o suporte.

Próximos passos​

  • Assinando um PDF: o fluxo PAdES completo, com a biblioteca de assinatura calculando o hash e finalizando o PDF.
  • Autenticação: permita que os usuários entrem com o certificado em nuvem.
  • Como funciona: SignatureSession para assinar vários documentos com uma única autorização.
Ver em Markdown