Autenticação com certificado - Rest PKI
O Rest PKI é um produto legado: continua recebendo correções de bugs e de segurança, mas novas integrações em nuvem devem usar o Rest PKI Core, que também atende à maioria das APIs do Rest PKI. Esta página é para integrações existentes com o Rest PKI. Veja a referência rápida do Rest PKI.
Os usuários entram na sua aplicação com o certificado digital: o Rest PKI emite um token de uso único, o Web PKI o assina com o certificado do usuário no navegador, e o Rest PKI verifica a assinatura e o certificado.
O código desta página é do projeto de exemplos em ASP.NET MVC: C# no servidor, com o Lacuna.RestPki.Client
1.24.1, e JavaScript no navegador, com o Web PKI.
Fluxo
- Servidor: inicie a autenticação com o contexto de segurança; o Rest PKI devolve um token.
- Navegador: o Web PKI lista os certificados do usuário; quando ele escolhe um,
signWithRestPki()assina com ele, usando o token. - Servidor: conclua a autenticação com o token; o Rest PKI devolve os resultados da validação e o certificado do usuário.
- Servidor: se os resultados forem válidos, encontre o seu usuário por um campo do certificado e faça o login dele.
| Etapa | Método do cliente | Endpoint |
|---|---|---|
| Início | StartWithWebPkiAsync(securityContextId) | POST Api/Authentications |
| Conclusão | CompleteWithWebPkiAsync(token) | POST Api/Authentications/{token}/Finalize |
1. Iniciar a autenticação
O servidor inicia a autenticação e mostra a página com o token, uma string de 22 caracteres, que diferencia maiúsculas de minúsculas e é segura para URLs. Ele não é o seu token de acesso à API.
var auth = Util.GetRestPkiClient().GetAuthentication();
var token = await auth.StartWithWebPkiAsync(Util.GetSecurityContextId());
base.SetNoCacheHeaders();
- O token vale para uma única autenticação. O sample envia headers que impedem o navegador de guardar a página em cache, para que o botão voltar não mostre uma página com um token já usado.
- A autenticação precisa ser concluída em até uma hora por padrão; em uma instância on-premises, a configuração
TimeToCompleteAuthenticationsmuda esse prazo (desde o Rest PKI 1.12.6). - O contexto de segurança decide quais certificados são aceitos; os samples usam
LacunaTestnos builds de debug, para aceitar os certificados de teste, ePkiBrazilnos demais. Veja Contexto de segurança. - Para ignorar erros por status de revogação desconhecido, inicie com um
AuthenticationOptionscujoIgnoreRevocationStatusUnknownsejatrue(desde o Rest PKI 1.16.0); o sample não faz isso.
2. Assinar o token no navegador
A página guarda o token em um campo oculto, com um <select> para os certificados e um botão Sign In que não é de envio: o formulário
é enviado por script quando o Web PKI termina.
O script inicializa o Web PKI com o endpoint do seu Rest PKI em restPkiUrl:
var pki = new LacunaWebPKI(_webPkiLicense);
pki.init({
ready: loadCertificates, // As soon as the component is ready we'll load the certificates.
defaultError: onWebPkiError, // Generic error callback defined below.
restPkiUrl: _restPkiEndpoint // REST PKI endpoint to communication between Web PKI.
});
Quando o usuário clica em Sign In, o script chama signWithRestPki() com o token e o certificado escolhido e depois envia o
formulário:
var selectedCertThumbprint = formElements.certificateSelect.val();
pki.signWithRestPki({
token: formElements.token,
thumbprint: selectedCertThumbprint
}).success(function () {
formElements.form.submit();
});
_webPkiLicensee_restPkiEndpointvêm das configuraçõesWebPkiLicenseeRestPkiEndpoint.RestPkiEndpointsó é necessário on-premises, e uma licença do Web PKI só para rodar em um host diferente delocalhost. Veja também Especificando a URL do Rest PKI.- O Web PKI troca os dados da assinatura diretamente com o Rest PKI.
3. Concluir a autenticação
De volta ao servidor, conclua a autenticação com o token. Se os resultados não forem válidos, mostre o que falhou; caso contrário, leia o certificado do usuário:
var auth = Util.GetRestPkiClient().GetAuthentication();
var validationResults = await auth.CompleteWithWebPkiAsync(model.Token);
if (!validationResults.IsValid) {
return View("Failed", validationResults);
}
return View("Success", new AuthenticationInfoModel() {
UserCert = auth.GetCertificate()
});
- O Rest PKI responde HTTP 200 tenha a autenticação dado certo ou não: verifique
IsValid.ValidationResults.ToString()lista todas as verificações, e o sample a mostra na página de falha. - A conclusão remove a autenticação: uma segunda chamada com o mesmo token falha.
- Se o navegador não assinou, a conclusão falha com
ClientSignatureNotSet(HTTP 422). Veja os códigos de retorno. GetCertificate()só pode ser chamado depois de um método de conclusão.
4. Fazer o login do usuário
Quando os resultados são válidos, o comentário do sample diz que o certificado é válido segundo o contexto de segurança escolhido no início
e que o usuário é o titular do certificado. Procure o seu usuário por um dos campos do certificado, como EmailAddress ou, em certificados ICP-Brasil,
PkiBrazil.Cpf; qual campo usar depende da sua aplicação.
O certificado (PKCertificate) tem SubjectName, EmailAddress, IssuerName, SerialNumber, ValidityStart, ValidityEnd,
ThumbprintSHA256 e, em certificados ICP-Brasil, PkiBrazil com CertificateType, Cpf, Cnpj, Responsavel, CompanyName,
DateOfBirth e os campos de RG e OAB.
TODO(docs): o que o Rest PKI verifica na conclusão, além da confiança no certificado segundo o contexto de segurança.
Erros
- Quando um limite da conta está definido e é excedido, o Rest PKI responde HTTP 429 com os headers
X-RateLimit-LimiteX-RateLimit-Remaining. - Para os demais códigos, veja os códigos de retorno e a referência rápida.