2012-08-14 12 views
9

uso un conector http de tomcat con autentificación de cliente. Si un cliente inicia una nueva conexión con mi servidor y envía su certificado, ¿puedo obtener el certificado y leer el nombre común del certificado entrante en mi código java? Si es así, ¿cómo?Leer el certificado entrante en Tomcat

gracias adi

+0

http://www.coderanch.com/t/438788/Security/Read-client-certificate-Servlet mirada hacia el final de la entrada. ¡Buena suerte! – mazaneicha

Respuesta

16

, usted puede obtener la cadena de certificados de cliente al obtener el atributo javax.servlet.request.X509Certificate en su HttpServletRequest. Esta es una matriz de X509Certificates donde la primera (posición 0) es el certificado del cliente real (el resto de la cadena puede estar presente si se requieren certificados CA intermedios).

X509Certificate certs[] = 
    (X509Certificate[])req.getAttribute("javax.servlet.request.X509Certificate"); 
// ... Test if non-null, non-empty. 

X509Certificate clientCert = certs[0]; 

// Get the Subject DN's X500Principal 
X500Principal subjectDN = clientCert.getSubjectX500Principal(); 

, entonces puede obtener los diversos RDN (nombre completo relativo) en este principal (por ejemplo, CN) como se describe en this answer:

import javax.naming.ldap.LdapName; 
import javax.naming.ldap.Rdn; 

String dn = subjectDN.getName(); 
LdapName ldapDN = new LdapName(dn); 
for(Rdn rdn: ldapDN.getRdns()) { 
    System.out.println(rdn.getType() + " -> " + rdn.getValue()); 
} 

(también se podría utilizar BouncyCastle de X509Name para obtener cada RDN.)

En un certificado X.509, el DN del sujeto es una secuencia ordenada de RDN, cada uno de los cuales es un conjunto de AVA (Aserciones de valor de atributo), por ejemplo CN=... o O=.... En principio, puede haber múltiples AVA por RDN, lo que causaría problemas aquí, pero esto es muy raro. Casi puede suponer que solo hay un AVA por RDN. (Tal vez this answer podría ser de interés.)

+0

gracias, todo funcionó muy bien al primer intento :-) para todo el mundo que utiliza axis2 y no sabe cómo obtener el HttpServletRequest: \t MessageContext context = MessageContext.getCurrentMessageContext(); \t HttpServletRequest requestProperty = (HttpServletRequest) context.getProperty (HTTPConstants.MC_HTTP_SERVLETREQUEST); – adihubba

+0

Obtengo null para req.getAttribute ("javax.servlet.request.X509Certificate"). ¿es necesario enviar una solicitud desde el mismo dominio coincidente? Intenté desde la máquina local (usando localhost) y también desde el servidor de desarrollo. – TechnoCrat

+0

@TechnoCrat Probablemente significa que (a) su servidor no está configurado para solicitar/requerir un certificado de cliente o (b) la lista de autoridades de certificación que envía cuando solicita un certificado de cliente no coincide con ninguno de los certificados de cliente que tiene en tu máquina. No se trata realmente de la coincidencia de "dominio", sino de la coincidencia de CA. – Bruno

0

crédito a mazaneicha:

 String cipherSuite = (String) req.getAttribute("javax.servlet.request.cipher_suite"); 

     if (cipherSuite != null) { 
      X509Certificate certChain[] = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate"); 
      if (certChain != null) { 
       for (int i = 0; i < certChaNin.length; i++) { 
        System.out.println ("Client Certificate [" + i + "] = " 
          + certChain[i].toString()); 
       } 
      } 
     } 
+0

No es necesario que obtenga y pruebe primero el conjunto de cifrado. – Bruno

Cuestiones relacionadas