2012-09-07 29 views
6

Me gustaría utilizar una autenticación de cliente X509 para un acceso seguro a la API.¿Cómo administrarías la autenticación X509 en una aplicación Django detrás de un proxy Nginx?

Los certificados X509 son generados por nuestra CA (memberca).

El objetivo es que:

  1. de conexión del cliente de la API mediante SSL
  2. Las personas con un certificado X509 válido desde nuestra memberca puede acceder a él
  3. Comprobamos que el certificado no ha revocado puede usar una CRL.

Creo que es posible que pueda gestionarlo directamente en la configuración de Nginx. ¿Cómo debo hacer eso?

¿Puedo hacerlo con Django? Entonces, ¿cómo debería hacerlo entonces? ¿Puedo conectar con cualquiera de las soluciones el certificado a un usuario?

Por ejemplo, ¿Nginx puede mapear algunos datos de certificados con un encabezado WSGI para que pueda hacer coincidir mi usuario?

+0

Acabo de iniciar http://github.com/novapost/django-x509 para implementar esto. – Natim

Respuesta

5

Ya configuré una configuración similar.

Primero, utilicé Apache2 para autenticar al usuario.

necesita habilitar mod_ssl, y tienen que definir (a nivel mundial):

  • SSLCertificateFile: puntos a su certificado de servidor codificado PEM;
  • SSLCertificateKeyFile: apunta a su clave de servidor con codificación PEM;
  • SSLCertificateChainFile: apunta a su lista de certificados de CA de PEM;
  • SSLCACertificatePath: apunta a la carpeta que contiene todos sus certificados de CA de PEM;
  • SSLCACertificateFile: apunta a su certificado de CA (debe tener el mismo valor que SSLCertificateChainFile);
  • SSLCARevocationPath: apunta a la carpeta que contiene toda su CRL;
  • SSLCARevocationFile: apunta a la lista de certificados revocados (su ca-bundle.crl)
  • SSLCARevocationCheck chain.

Ahora su servidor está listo para verificar un certificado de cliente X.509.

Si no desea utilizar apache2 como servidor web frontal, puede configurarlo como un proxy inverso habilitando mod_proxy.

Usted sólo tiene que definir un host virtual como esto:

<VirtualHost *:443> 
    ServerName test.example.com:443 
    ServerAdmin [email protected] 

    RequestHeader set Front-End-Https "On" 

    # Here I define two headers, Auth-User and Remote-User 
    # They will contain the key SSL_CLIENT_S_DN_CN which is the name of the 
    # client certificate's owner. 
    <If "-n %{SSL_CLIENT_S_DN_CN}"> 
     # If the key doesn't exist, it means that the certificate wasn't sent or 
     # it was revoked. 

     RequestHeader set Auth-User "%{SSL_CLIENT_S_DN_CN}s" 
     RequestHeader set Remote-User "%{SSL_CLIENT_S_DN_CN}s" 
    </If> 

    # Now enable SSL, and SSL via the proxy 
    SSLEngine on 
    SSLProxyEngine on 

    ## Require a client certificate 
    # SSLVerifyClient require 
    ## NB: I prefer set it to optional, in order to allow the user 
    ##  to connect to my application with a degraded mode (login+password) 
    ##  It's easy to detect if the user was authenticated by apache by looking 
    ##  at HTTP_AUTH_USER or HTTP_REMOTE_USER 

    SSLVerifyClient optional 

    # Maximum depth of CA Certificates in Client Certificate verification 
    SSLVerifyDepth 4 

    # Now, I pass all of this to my application, which is runned in nginx for example : 
    <Location /> 
     ProxyPass http://<applciation host> 
     ProxyPassReverse http://<applciation host> 
     ProxyPreserveHost on 
     # Send all informations about the client/server certificates to the application 
     SSLOptions +StdEnvVars +ExportCertData 
    </Location> 
</VirtualHost> 

Y ahora, con Django, sólo hay que activar backend de autenticación remota como se describe here.

Todas las informaciones extraídas del certificado del cliente se envían a la aplicación, por lo que puede usarlas utilizando el objeto de solicitud (y/o con middlewares).

Espero que te haya ayudado.

+0

Esto es realmente interesante, muchas gracias. Comprobaré si es posible una solución similar con Nginx. – Natim

1

Estamos haciendo eso con Apache dejando que mod_ssl se encargue de la validación del certificado y las comprobaciones de revocación. Si el certificado es válido y no se revoca, simplemente colocamos el CN ​​del certificado en un encabezado HTTP y estamos recuperando con Django y haciendo coincidir con nuestra base de datos de usuarios.

Cuestiones relacionadas