2009-05-15 21 views
7

Estoy tratando de leer un certificado X509 utilizando Request.ClientCertificate pero no se devuelve nada. El certificado definitivamente se adjunta a la solicitud porque puedo obtener la información del certificado de la página que envía la solicitud.leer certificado de cliente de httprequest C#

He intentado leer el certificado desde diferentes lugares pero parece que no funciona.

Empecé con el código de this KB Article. En la página solicitada traté de imprimir cierta información sobre el certificado, pero no se devolvió nada en la respuesta.

Esto se ejecuta en IIS 5.1 y la comunicación es a través de SSL. Esto se debe hacer utilizando la versión 2 de .Net framework

¿Por qué parece que el certificado desaparece?

+0

No vi esto antes de hacer básicamente la misma pregunta hace unos minutos. Es un poco desalentador que aún no tenga una respuesta ... – DaveN59

+1

¿Qué punto del ciclo de vida está tratando de recuperar? ¿Página OnInit, OnLoad, Master Page, Global.asax, etc.? – CodeRot

+0

Intento recuperarlo en el método Page_Load – Sean

Respuesta

1

Ok, no está del todo claro, pero usted tiene un sitio web que requiere que los clientes se autentiquen usando certificados. Porque eso es para lo que es la propiedad Request.ClientCertificate.

Lo digo porque hay algo extraño en su pregunta.

"Puedo obtener la información del certificado de la página que envía la solicitud".

Las páginas en general realmente no envían solicitudes a los clientes.

Para obtener el certificado del servidor, puede abrir el X509Store y examinar los certs para encontrar el que tenga el CN ​​que necesita.

+0

la "página que envía la solicitud" es el cliente en este caso. Adjunta un certificado X509 a la solicitud de la página que intento utilizar la propiedad Request.ClientCertificate en – Sean

2

No estoy seguro de qué necesita el certificado del cliente, pero si lo está utilizando para su propia autenticación o autorización personalizada, puede considerar utilizar la infraestructura de seguridad del servidor web en lugar de implementar la suya propia. Por ejemplo, puede configurar IIS para que requiera certificados de cliente, asignar los certs a cuentas de usuario y usar autenticación basada en Windows. Por supuesto, esto no necesariamente funciona para su dominio problemático.

11

Hace un tiempo escribí una página web de identificación que buscaba un certificado de cliente y si se encontraba, mostraba la información del certificado. Creo que eso es lo que está buscando ... Aquí está la página:

<%@ Page Language="C#" Trace="false" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<%@ Import Namespace="System.Security.Cryptography.X509Certificates" %> 
<%@ Import Namespace="System.Security.Cryptography" %> 

<script runat="server"> 
    //protected void Page_Load(object sender, EventArgs e) 
    //{ } 

    void LoadCertInfo() 
    { 
     string para = "<div style='margin: 10px 0 0 0; font-weight: bold'>{0}</div>"; 
     string subpara = "<div style='margin-left: 15px; font-size: 90%'>{0}</div>"; 

     if (Page.Request.ClientCertificate.IsPresent) 
     { 
      Response.Write("<hr /><div style='width: 500px; margin: 20px auto'>"); 
      Response.Write("<h3 style='width: 500px; margin: 20px auto'>Client Certificate Information</h3>"); 
      try 
      { 
       X509Certificate2 x509Cert2 = new X509Certificate2(Page.Request.ClientCertificate.Certificate); 

       Response.Write(string.Format(para, "Issued To:")); 
       Response.Write(string.Format(subpara, x509Cert2.Subject)); 

       Response.Write(string.Format(para, "Issued By:")); 
       Response.Write(string.Format(subpara, x509Cert2.Issuer)); 

       Response.Write(string.Format(para, "Friendly Name:")); 
       Response.Write(string.Format(subpara, string.IsNullOrEmpty(x509Cert2.FriendlyName) ? "(None Specified)" : x509Cert2.FriendlyName)); 

       Response.Write(string.Format(para, "Valid Dates:")); 
       Response.Write(string.Format(subpara, "From: " + x509Cert2.GetEffectiveDateString())); 
       Response.Write(string.Format(subpara, "To: " + x509Cert2.GetExpirationDateString())); 

       Response.Write(string.Format(para, "Thumbprint:")); 
       Response.Write(string.Format(subpara, x509Cert2.Thumbprint)); 

       //Response.Write(string.Format(para, "Public Key:")); 
       //Response.Write(string.Format(subpara, x509Cert2.GetPublicKeyString())); 

       #region EKU Section - Retrieve EKU info and write out each OID 
       X509EnhancedKeyUsageExtension ekuExtension = (X509EnhancedKeyUsageExtension)x509Cert2.Extensions["Enhanced Key Usage"]; 
       if (ekuExtension != null) 
       { 
        Response.Write(string.Format(para, "Enhanced Key Usages (" + ekuExtension.EnhancedKeyUsages.Count.ToString() + " found)")); 

        OidCollection ekuOids = ekuExtension.EnhancedKeyUsages; 
        foreach (Oid ekuOid in ekuOids) 
         Response.Write(string.Format(subpara, ekuOid.FriendlyName + " (OID: " + ekuOid.Value + ")")); 
       } 
       else 
       { 
        Response.Write(string.Format(para, "No EKU Section Data")); 
       } 
       #endregion // EKU Section 

       #region Subject Alternative Name Section 
       X509Extension sanExtension = (X509Extension)x509Cert2.Extensions["Subject Alternative Name"]; 
       if (sanExtension != null) 
       { 
        Response.Write(string.Format(para, "Subject Alternative Name:")); 
        Response.Write(string.Format(subpara, sanExtension.Format(true))); 
       } 
       else 
       { 
        Response.Write(string.Format(para, "No Subject Alternative Name Data")); 
       } 

       #endregion // Subject Alternative Name Section 

       #region Certificate Policies Section 
       X509Extension policyExtension = (X509Extension)x509Cert2.Extensions["Certificate Policies"]; 
       if (policyExtension != null) 
         { 
          Response.Write(string.Format(para, "Certificate Policies:")); 
          Response.Write(string.Format(subpara, policyExtension.Format(true))); 
         } 
         else 
         { 
          Response.Write(string.Format(para, "No Certificate Policies Data")); 
         } 
       #endregion //Certificate Policies Section 


       // Example on how to enumerate all extensions 
       //foreach (X509Extension extension in x509Cert2.Extensions) 
       // Response.Write(string.Format(para, extension.Oid.FriendlyName + "(" + extension.Oid.Value + ")")); 
      } 
      catch (Exception ex) 
      { 
       Response.Write(string.Format(para, "An error occured:")); 
       Response.Write(string.Format(subpara, ex.Message)); 
       Response.Write(string.Format(subpara, ex.StackTrace)); 
      } 
      finally 
      { 
       Response.Write("</div>"); 
      } 
     } 
    } 
</script> 
<html> 
    <head runat="server"> 
    <title><% Page.Response.Write(System.Environment.MachineName); %></title> 
    </head> 
    <body> 
     <% LoadCertInfo(); %> 
    </body> 
</html> 
+0

¿Cómo es esta la mejor respuesta? El OP dijo que ya está usando 'Page.Request.ClientCertificate.Certificate' pero que está devolviendo' null'. Esto no hace nada para ayudar a resolver el problema. – jtate

Cuestiones relacionadas