Primeiros passos para integração - Rest PKI Core
Este artigo leva você do zero até uma primeira chamada bem-sucedida ao Rest PKI Core. Você vai:
- Obter as credenciais: o endpoint da instância e uma chave de API
- Configurar a biblioteca cliente da sua linguagem de programação ou chamar a API REST diretamente
- Fazer uma primeira chamada para verificar se está tudo pronto
Como a integração funciona
A sua aplicação se comunica com o Rest PKI Core por uma API REST, autenticada por uma chave de API. As chamadas são sempre feitas pelo backend da aplicação: a chave de API dá acesso à sua organização e, por isso, nunca deve chegar a um navegador ou a um aplicativo móvel.
Quando uma operação depende do usuário, como escolher um certificado e assinar um documento ou tirar uma selfie para uma verificação biométrica, você não precisa construir essas páginas. O backend cria uma sessão, o Rest PKI Core retorna uma URL e o usuário é enviado a uma página hospedada pelo Rest PKI Core. Quando termina, o usuário volta à sua aplicação, que obtém os resultados pela API. Veja sessões de assinatura e sessões de biometria.
Obtenha as credenciais
Você precisa de dois parâmetros:
| Parâmetro | Descrição |
|---|---|
| Endpoint | Endereço da instância do Rest PKI Core. Na instância SaaS, é https://core.pki.rest/. Numa instância própria, é o endereço do dashboard dela, como https://restpki.suaempresa.com.br/ |
| Chave de API | Chave que identifica a aplicação e autentica as chamadas dela. Tem o formato MyApp|0f3c…: um prefixo tirado do nome da aplicação, um | e 64 caracteres hexadecimais |
Se você usa a instância SaaS e a sua empresa ainda não tem acesso a ela, entre em contato com o nosso suporte ao desenvolvedor. Se você usa uma instância on-premises própria e ainda não tem uma organização com a qual trabalhar, veja Criação de organização.
Crie uma chave de API
As chaves de API pertencem a aplicações. Assim que conseguir entrar no dashboard, crie uma aplicação para o seu sistema e uma chave para ela:
- Entre no dashboard da instância
- No menu lateral, clique em Aplicações e depois em Adicionar
- Em Nova Aplicação, preencha um Nome para a aplicação. Se for pedida uma Organização, escolha aquela em que o seu sistema vai trabalhar
- Em Papéis, marque Operador (veja Escolhendo os papéis abaixo)
- Clique em Criar
- Na página da aplicação, clique em Chaves e depois em Adicionar
- Em Nova Chave de Aplicação, preencha uma Descrição (por exemplo, o ambiente que vai usar a chave) e escolha uma Expiração (veja Expiração da chave abaixo); depois clique em Criar
- Copie a chave exibida no diálogo Chave criada e guarde-a em um local seguro. Não será possível vê-la novamente: se você a perder, crie uma nova chave
Quem tiver a chave pode agir sobre a sua organização com os papéis da aplicação dela. Guarde-a como guardaria uma senha: num cofre de segredos como o Azure Key Vault, numa variável de ambiente ou, durante o desenvolvimento, nos segredos do usuário (user secrets) do .NET. Nunca faça commit dela no controle de versão e nunca a envie a um navegador ou a um aplicativo móvel.
Escolhendo os papéis
Os papéis de uma aplicação definem o que as chaves dela podem fazer. Dê à aplicação apenas os papéis de que ela precisa:
| Papel | O que permite |
|---|---|
| Operador | As operações de uma integração: criar e usar sessões de assinatura, assinar documentos, inspecionar assinaturas, autenticar usuários com certificados, emitir carimbos de tempo, executar sessões de biometria, adicionar marcas e carimbos aos documentos e consultar transações. É o papel de que a maioria das integrações precisa |
| Monitor | Consultar transações, sessões de biometria, cadastros em lote e faturas, sem executar nenhuma operação |
| Gerente | Tudo o que um Operador faz, além de gerenciar as configurações da organização e os contextos de segurança. Pode ver aplicações e usuários, mas não gerenciá-los |
| Administrador | Tudo, inclusive gerenciar aplicações e usuários |
Expiração da chave
A Expiração de uma chave pode ser Em 1 ano, Em 2 anos ou Nunca expira. Quando uma chave expira, as chamadas feitas com ela passam a falhar com HTTP 401; por isso, se escolher uma chave que expira, planeje a substituição dela: uma aplicação pode ter mais de uma chave, o que permite criar a nova chave e passar o sistema a usá-la antes que a antiga expire.
Escolha como chamar a API
As APIs do Rest PKI Core são REST simples com JSON, mas você não precisa lidar com HTTP diretamente. A Lacuna oferece bibliotecas cliente que encapsulam a API nas convenções de cada linguagem, junto com projetos de exemplo que as usam:
| Linguagem | Pacote | Código-fonte | Exemplos |
|---|---|---|---|
| .NET | Lacuna.RestPkiCore.Client no NuGet | — | PkiSuiteSamples/dotnet |
| PHP | lacuna/restpkicore-client no Packagist | GitHub | PkiSuiteSamples/php |
| Java | com.lacunasoftware.restpki:restpkicore-client no Maven Central | GitHub | PkiSuiteSamples/java |
| Node.js | restpki-core-client no npm | GitHub | PkiSuiteSamples/nodejs |
Vá para a seção da sua linguagem:
Para qualquer outra linguagem, chame a API diretamente.
.NET
Adicione ao seu projeto o pacote do NuGet Lacuna.RestPkiCore.Client:
dotnet add package Lacuna.RestPkiCore.Client
O pacote é compilado para o .NET Standard 2.0, então roda no .NET 5 ou posterior, no .NET Core 2.0 ou posterior e no .NET Framework 4.6.1 ou posterior (a Microsoft recomenda a 4.7.2 ou posterior para bibliotecas .NET Standard 2.0).
O pacote se chama Lacuna.RestPkiCore.Client, mas as classes dele ficam no namespace Lacuna.RestPki.Client.
Aplicações ASP.NET Core
Registre os serviços do Rest PKI Core no Program.cs, vinculando as opções deles à seção de configuração RestPki:
builder.Services.AddRestPki().Configure(builder.Configuration.GetSection("RestPki"));
Em seguida, adicione a seção ao appsettings.json, sem a chave de API:
{
"RestPki": {
"Endpoint": "https://core.pki.rest/"
}
}
Forneça a chave de API por uma fonte que fique fora do controle de versão. Durante o desenvolvimento, use os segredos do usuário:
dotnet user-secrets set "RestPki:ApiKey" "YOUR_API_KEY"
Em produção, defina a variável de ambiente RestPki__ApiKey ou use um cofre de segredos como o Azure Key Vault. O ASP.NET Core combina
essas fontes na mesma seção RestPki.
Onde a aplicação precisar chamar o Rest PKI Core, peça um IRestPkiService por injeção de dependência:
using Lacuna.RestPki.Client;
public class SignatureController : Controller {
private readonly IRestPkiService restPkiService;
public SignatureController(IRestPkiService restPkiService) {
this.restPkiService = restPkiService;
}
...
}
O AddRestPki() também registra o IRestBioService, o serviço usado nas sessões de biometria.
Se preferir definir as opções no código, passe-as ao AddRestPki():
builder.Services.AddRestPki(options => { options.Endpoint = ...; options.ApiKey = ...; });
Outras aplicações .NET
Se a aplicação não usa a injeção de dependência do ASP.NET Core, como numa aplicação .NET Framework ou de console, obtenha um
IRestPkiService da classe estática RestPkiServiceFactory:
using Lacuna.RestPki.Client;
var restPkiService = RestPkiServiceFactory.GetService(new RestPkiOptions() {
Endpoint = ConfigurationManager.AppSettings["RestPkiEndpoint"],
ApiKey = ConfigurationManager.AppSettings["RestPkiApiKey"],
});
Neste exemplo, os parâmetros vêm da seção appSettings do arquivo web.config ou app.config, mas podem vir de onde você preferir. Para
sessões de biometria, use RestPkiServiceFactory.GetBioService(), que recebe os mesmos parâmetros.
Cada chamada à RestPkiServiceFactory cria um novo cliente HTTP; por isso, crie o serviço uma vez e reutilize-o, por exemplo num campo
estático, em vez de criar um a cada requisição.
Opções
O RestPkiOptions tem as propriedades a seguir, que também podem ser definidas na seção de configuração RestPki:
| Propriedade | Descrição |
|---|---|
Endpoint | Endereço da instância do Rest PKI Core. Se o endereço tiver um caminho, termine-o com uma barra (https://suaempresa.com.br/restpki/); caso contrário, o último segmento do caminho é descartado |
ApiKey | A chave de API da aplicação |
CultureName | Cultura das respostas da API, como en-US, pt-BR ou es-ES (veja Cultura abaixo). Também disponível como Culture, do tipo CultureInfo |
TimeoutSeconds | Quanto tempo esperar por cada resposta, em segundos. Se não for definido, o cliente espera 60 segundos. Também disponível como Timeout, do tipo TimeSpan |
Cultura
O cliente informa ao Rest PKI Core qual cultura usar em cada chamada e, por padrão, usa a cultura da thread atual
(Thread.CurrentThread.CurrentUICulture). Isso funciona bem quando a aplicação define a cultura de cada requisição, como o ASP.NET Core faz
com a localização de requisições (request localization).
Para usar sempre a mesma cultura, independentemente da thread, defina CultureName. No ASP.NET Core, adicione a propriedade à seção de
configuração:
{
"RestPki": {
"Endpoint": "https://core.pki.rest/",
"CultureName": "en-US"
}
}
Nos demais casos, defina-a no RestPkiOptions:
var restPkiService = RestPkiServiceFactory.GetService(new RestPkiOptions() {
...,
CultureName = "en-US",
});
Erros
Os métodos do IRestPkiService podem lançar as seguintes exceções:
| Exceção | Quando |
|---|---|
RestPkiExceptionV2 | A API rejeitou a requisição (HTTP 422). Compare a propriedade ErrorCode, do tipo ErrorCodesV2, com os códigos de erro. A propriedade ErrorMessage descreve o erro em inglês e serve para os seus logs, não para os seus usuários |
ValidationException | Um certificado ou uma assinatura não passou na validação. A propriedade ValidationResults indica o que falhou |
RestForbiddenOperationException | A aplicação não tem um papel que permita a operação (HTTP 403, veja Escolhendo os papéis) |
RestErrorException | Qualquer outro erro HTTP, como 401 por uma chave de API ausente ou inválida. A propriedade StatusCode tem o código de status HTTP (veja Códigos de status HTTP) |
RestUnreachableException | Não foi possível acessar o endpoint: verifique o endereço do endpoint e a sua rede |
TimeoutException | A resposta demorou mais que TimeoutSeconds |
RestPkiExceptionV2 e ValidationException ficam no namespace Lacuna.RestPki.Client, e as demais classes Rest…Exception, no namespace
Lacuna.RestClient. Todas derivam de Lacuna.RestClient.RestException; para tratar qualquer erro da API num único lugar, capture
RestException (e TimeoutException, que é uma exceção padrão do .NET).
PHP
Adicione ao seu projeto o pacote do Composer lacuna/restpkicore-client (se ainda não tem o Composer, obtenha-o aqui):
composer require lacuna/restpkicore-client
O pacote requer o PHP 5.5 ou posterior e usa o Guzzle 6 ou 7 para fazer as chamadas HTTP. Ele é de código aberto, hospedado no GitHub: fique à vontade para fazer um fork se precisar personalizá-lo.
Crie um RestPkiService, que implementa RestPkiServiceInterface, passando a ele um RestPkiCoreClient construído com o endpoint e a
chave de API:
use Lacuna\RestPki\RestPkiOptions;
use Lacuna\RestPki\RestPkiCoreClient;
use Lacuna\RestPki\RestPkiService;
$options = new RestPkiOptions('https://core.pki.rest/', getenv('RESTPKI_API_KEY'));
$client = new RestPkiCoreClient($options);
$service = new RestPkiService($client);
Neste exemplo, a chave de API vem da variável de ambiente RESTPKI_API_KEY, o que a mantém fora do código.
Cultura
Para definir a cultura das respostas da API, passe-a como terceiro parâmetro do RestPkiOptions:
$options = new RestPkiOptions('https://core.pki.rest/', getenv('RESTPKI_API_KEY'), 'en-US');
Erros
Todas as exceções a seguir ficam no namespace Lacuna\RestPki:
| Exceção | Quando |
|---|---|
RestPkiException | A API rejeitou a requisição (HTTP 422). getErrorCode() retorna o código de erro e getDetail() descreve o erro, para os seus logs |
ValidationException | Um certificado ou uma assinatura não passou na validação |
RestErrorException | Qualquer outro erro HTTP. getStatusCode() retorna o código de status HTTP (veja Códigos de status HTTP) |
RestUnreachableException | Não foi possível acessar o endpoint |
Exemplos em PHP
No nosso repositório de exemplos, as pastas cujo nome
termina em -rest-core usam o Rest PKI Core. O endpoint e a chave de API são definidos na entrada restPkiNg do
config.php.
Java
Adicione ao seu projeto o pacote com.lacunasoftware.restpki:restpkicore-client, do Maven Central. Ele requer o Java 8 ou posterior.
Com o Gradle, no build.gradle:
repositories {
mavenCentral()
}
dependencies {
implementation 'com.lacunasoftware.restpki:restpkicore-client:1.4.0'
}
Com o Maven, no pom.xml:
<dependency>
<groupId>com.lacunasoftware.restpki</groupId>
<artifactId>restpkicore-client</artifactId>
<version>1.4.0</version>
</dependency>
Consulte o Maven Central para saber qual é a versão mais recente.
Não confunda com o com.lacunasoftware.restpki:restpki-core-client, um pacote mais antigo que não é mais atualizado.
O pacote é de código aberto, hospedado no GitHub: fique à vontade para fazer um fork se precisar personalizá-lo.
Obtenha um RestPkiService de RestPkiServiceFactory.getService(), passando um RestPkiOptions com o endpoint e a chave de API:
import com.lacunasoftware.restpkicore.RestPkiOptions;
import com.lacunasoftware.restpkicore.RestPkiService;
import com.lacunasoftware.restpkicore.RestPkiServiceFactory;
RestPkiOptions options = new RestPkiOptions();
options.setEndpoint("https://core.pki.rest/");
options.setApiKey(System.getenv("RESTPKI_API_KEY"));
RestPkiService service = RestPkiServiceFactory.getService(options);
Neste exemplo, a chave de API vem da variável de ambiente RESTPKI_API_KEY, o que a mantém fora do código. Se a aplicação acessa a
internet por um proxy, defina-o com options.setProxy().
Cultura
Para definir a cultura das respostas da API, chame setCulture():
options.setCulture("en-US");
Erros
Os métodos do RestPkiService declaram throws Exception. Estas são as exceções que eles lançam, todas no pacote
com.lacunasoftware.restpkicore:
| Exceção | Quando |
|---|---|
RestPkiException | A API rejeitou a requisição (HTTP 422). getErrorCode() retorna o código de erro |
ValidationException | Um certificado ou uma assinatura não passou na validação |
RestResourceNotFoundException | O recurso não foi encontrado (HTTP 404) |
RestErrorException | Qualquer outro erro HTTP. getStatusCode() retorna o código de status HTTP (veja Códigos de status HTTP) |
RestUnreachableException | Não foi possível acessar o endpoint |
Exemplos em Java
No nosso repositório de exemplos, os controllers cujo
nome termina em CoreController, como SignatureSessionRestCoreController, usam o Rest PKI Core. O endpoint e a chave de API são
definidos em rest-pki-core, no application.yml.
Chamando a API diretamente
As APIs do Rest PKI Core são RESTful, recebem e retornam JSON e, por isso, são fáceis de chamar em qualquer linguagem de programação moderna. Se a aplicação usa uma linguagem sem biblioteca cliente, chame-as diretamente:
- URL: acrescente o caminho relativo da API ao endpoint. Por exemplo,
api/signature-sessionsna instância SaaS éhttps://core.pki.rest/api/signature-sessions - Autenticação: passe a chave de API no header
X-Api-Keyde todas as requisições - Corpo: envie JSON com o header
Content-Type: application/json
Por exemplo:
POST https://core.pki.rest/api/signature-sessions
X-Api-Key: MyApp|0f3c...
Content-Type: application/json
Todas as APIs, com as requisições e respostas, estão descritas na referência da API. Numa instância
própria, a referência fica no caminho swagger do endpoint, como https://restpki.suaempresa.com.br/swagger.
Códigos de status HTTP
A API responde com os seguintes códigos de status HTTP:
| Código | Significado |
|---|---|
| 200 (OK) | A requisição foi bem-sucedida. A resposta depende da API: veja a referência da API |
| 400 (Bad Request) | A requisição está malformada; por exemplo, falta um campo obrigatório |
| 401 (Unauthorized) | A chave de API está ausente, é inválida ou expirou |
| 403 (Forbidden) | A chave de API é válida, mas a aplicação dela não tem um papel que permita a operação (veja Escolhendo os papéis) |
| 422 (Unprocessable Entity) | A API rejeitou a requisição, normalmente por causa de um parâmetro que precisa ser corrigido. O corpo é um ErrorModel |
| 500 (Internal Server Error) | Ocorreu um erro inesperado. O campo exceptionCode do corpo ajuda a diagnosticar o problema: informe-o ao entrar em contato com o suporte |
ErrorModel
Quando a API responde com 422 (Unprocessable Entity), o corpo é um ErrorModel, chamado ErrorModelV2 na referência da API,
com os seguintes campos:
| Campo | Tipo | Descrição |
|---|---|---|
code | string | O código de erro (veja os códigos de erro). Escreva o tratamento de erros com base neste campo |
message | string | Descrição do erro, em inglês. Serve para os seus logs, não para os seus usuários, já que não é localizada |
details | object | Informações adicionais sobre o erro, quando houver |
validationResults | object | Quando o código é ValidationError, os resultados da validação do certificado ou da assinatura que falhou |
Por exemplo:
{
"code": "SignatureSessionNotFound",
"message": "Signature session not found: 00000000-0000-0000-0000-000000000000"
}
Cultura
A API observa o header de requisição Accept-Language, que muda a cultura dos textos que a API retorna. As culturas suportadas são:
en-US(ou apenasen)pt-BR(ou apenaspt)es-ES(ou apenases)
As mensagens de erro não são afetadas por esse header; por isso, devem ser registradas no log, e não exibidas aos seus usuários. Para
mostrar um erro a um usuário, associe o code dele a uma mensagem própria.
Faça uma primeira chamada
Com as credenciais e a biblioteca cliente prontas, verifique se tudo funciona.
Primeiro, verifique o endpoint: abra o endereço api/system/info do endpoint num navegador, como
https://core.pki.rest/api/system/info. Esse endereço não exige chave de API e retorna a versão da
instância:
{"productName":"Lacuna Rest PKI Core","productVersion":"5.0.5 RTM","spaVersion":"...","timestamp":"..."}
Depois, verifique a chave de API criando uma sessão de assinatura. Em .NET:
using Lacuna.RestPki.Api.SignatureSessions;
var response = await restPkiService.CreateSignatureSessionAsync(new CreateSignatureSessionRequest() {
ReturnUrl = "https://localhost:5001/signature-callback",
});
// Send the user to response.RedirectUrl
Chamando a API diretamente:
curl -X POST "https://core.pki.rest/api/signature-sessions" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "returnUrl": "https://localhost:5001/signature-callback" }'
A resposta traz o ID da sessão e a URL da página de assinatura dela:
{
"sessionId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"redirectUrl": "https://core.pki.rest/..."
}
Abra a redirectUrl num navegador para ver a página em que os seus usuários vão assinar. Se, em vez disso, a chamada falhar:
- 401: a chave de API não foi enviada ou está errada. Verifique se você copiou a chave inteira, incluindo o nome da aplicação antes do
| - 403: a aplicação não tem o papel Operador (veja Escolhendo os papéis)
- Endpoint inacessível: verifique o endereço do endpoint e se o seu servidor consegue acessá-lo
Próximos passos
- Sessões de assinatura: permita que os seus usuários assinem documentos numa página hospedada pelo Rest PKI Core
- Assinaturas em duas etapas: assine na sua própria página com o Web PKI, ou com uma chave guardada no servidor
- Sessões de biometria: prova de vida, cadastro, autenticação e identificação facial e captura de documento
- Webhooks: seja avisado quando um documento for assinado
- Referenciando arquivos: as formas de enviar documentos à API
- Utilitário cliente do Rest PKI: assine documentos pela linha de comando e a partir de aplicações desktop
- Solicitando carimbos de tempo: use o Rest PKI Core como provedor de carimbos de tempo
- Códigos de erro: os códigos que a API pode retornar