2012-08-14 10 views
9

uso un connettore http tomcat con autenticazione client. Se un client avvia una nuova connessione al mio server e invia il suo certificato, posso ottenere il certificato e leggere il nome comune dal certificato in entrata nel mio codice java. Se sì, come?Leggere il certificato in entrata in Tomcat

grazie adi

+0

http://www.coderanch.com/t/438788/Security/Read-client-certificate-Servlet sguardo verso la fine del post. In bocca al lupo! – mazaneicha

risposta

16

è possibile ottenere la catena di certificati client ottenere l'attributo javax.servlet.request.X509Certificate sul HttpServletRequest. Questo è un array di X509Certificates dove il primo (posizione 0) è il vero certificato client (il resto della catena potrebbe essere presente se sono richiesti certificati CA intermedi).

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(); 

È possibile quindi ottenere i vari RDNs (nome distinto relativo) di questo principio (ad esempio CN), come descritto nella 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()); 
} 

(si potrebbe anche usare BouncyCastle di X509Name per ottenere ogni RDN.)

In un certificato X.509, il DN soggetto è una sequenza ordinata di RDN, ognuno dei quali è un insieme di AVA (Attribute Value Assertions), ad esempio CN=... o O=.... In linea di principio, possono esserci più AVA per RDN, che potrebbero causare problemi qui, ma questo è molto raro. Si può quasi presumere che ci sia solo un AVA per RDN. (Forse this answer potrebbero essere di interesse.)

+0

grazie, tutto ha funzionato molto bene al primo tentativo :-) per tutti coloro che utilizzano l'asse2 e non sa come accedere a HttpServletRequest: \t Contesto MessageContext = MessageContext.getCurrentMessageContext(); \t HttpServletRequest requestProperty = (HttpServletRequest) context.getProperty (HTTPConstants.MC_HTTP_SERVLETREQUEST); – adihubba

+0

Ottengo null per req.getAttribute ("javax.servlet.request.X509Certificate"). è richiesto per inviare una richiesta dallo stesso dominio corrispondente? Ho provato dalla macchina locale (usando localhost) e anche dal server di sviluppo. – TechnoCrat

+0

@TechnoCrat Questo probabilmente significa che (a) il tuo server non è configurato per richiedere/richiedere un certificato client o (b) l'elenco delle autorità di certificazione che invia quando richiede un certificato cliente non corrisponde a nessuno dei certificati client che hai sulla tua macchina. Non si tratta della corrispondenza "dominio" ma della corrispondenza CA. – Bruno

0

credito 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

Non è necessario ottenere e testare prima la suite di crittografia. – Bruno

Problemi correlati