Descobri que ao acessar um aplicativo da Web que usa a autenticação de certificado de cliente executada no Tomcat / APR (no Windows) com o Firefox ou o Chrome, o certificado do cliente é "perdido" após um breve período. Para o aplicativo, parece que o certificado do cliente não foi enviado.
Exemplo de código (fragmento JSP):
User client cert data:
<%= ((java.security.cert.X509Certificate[])
request.getAttribute("javax.servlet.request.X509Certificate"))[0].
getSubjectX500Principal().toString()%>
Após algumas atualizações da página (onde mostrará o DN do certificado do cliente), a página falhará com um NullPointerException, pois request.getAttribute retornará null . Isso geralmente acontece em menos de um minuto. Para ser mais preciso: ao recarregar uma vez por segundo, o problema ocorre quase sempre após 30 segundos. Depois disso, cada solicitação falhará da mesma maneira, até que eu reinicie o tomcat (ou reinicie o Firefox, ou apenas desmarque "Active Logins" no Firefox e selecione novamente o certificado em uma nova conexão). Após a reinicialização, o problema sempre retorna (e desaparece por 30 segundos se eu reiniciar novamente).
Isso acontece com o Firefox (v39 e v40) e com o Chrome (v44), mas não com o IE v11.
Também ocorre com diferentes versões do tomcat e Java (e bitness do SO).
Um caso de teste usando as versões mais recentes é:
- faça o download e extraia o apache-tomcat-8.0.24-windows-x64.zip
- na pasta webapps , crie uma pasta chamada cert , crie um arquivo chamado ccertA.jsp que contenha o snippet de código acima
-
no server.xml adicione uma linha:
< Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
secure="true" scheme="https" maxThreads="150" URIEncoding="UTF-8"
SSLVerifyClient="opcional" SSLProtocol="TLSv1 + TLSv1.1 + TLSv1.2"
SSLPassword="testing" SSLEnabled="true"
SSLCertificateKeyFile="C: /your_server_key_private.pem"
SSLCertificateFile="C: / your_server_key _public.pem"
SSLCACertificateFile="C: /supported_client_CAs.pem" / >
-
inicie o tomcat executando startup.bat
- abra a página link e mantenha-a atualizada a cada alguns segundos
(veja o erro abaixo para um testcase completo com todos os arquivos necessários, incluindo arquivos de certificado)
Se eu não usar o APR (excluindo o arquivo tcnative-1.dll e adaptando a sintaxe do conector para JSSE), o problema não acontecerá.
Versões experimentadas, todas tendo o problema:
- apache-tomcat-8.0.24-windows-x64 (também versão de 32 bits)
- apache-tomcat-6.0.44-windows-x64
- Atualizações do Java 1.6.0 12 e 45
- Atualização do Java 1.8 51
- Windows 7 Pro SP1 de 64 bits
- Windows 7 Pro SP1 de 32 bits
- Windows 8.1 Pro de 64 bits
- Windows 10 Início de 64 bits
- Versões do Firefox 39.0 39.0.3 e 44
- Chrome v44
- Ubuntu 14.04 LTS 64 bits / tomcat 7.0.52-1ubuntu0.3 / libapr1: amd64 1.5.0-1 / libtcnative-1: amd64 1.1.29-1
Uma questão semelhante foi discutida na lista de usuários do tomcat em 2010: Certificado de cliente passado após 1 minuto de tempo limite (SSL, APR) , mas sem solução. Eu postei por lá recentemente ( SSL do Firefox com certificado de cliente perdedor da APR tem um mais detalhes), mas basicamente é apenas o meu monólogo.
Editar: informações de certificado
Originalmente, testei com um certificado de servidor emitido pela minha CA de teste particular. Agora eu também tentei com um certificado "real" emitido pela CA confiável. (Eu usei meu certificado pessoal. O navegador reclamou da atenuação do nome do host que eu cliquei).
Editar: relatório de erros
Relatado como Bug 58244 - SSL bidirecional perde certificado de cliente após alguns pedidos
Sugestões sobre como depurar o problema são bem-vindas.