I'm trying to get the client's certificate and sign an xml file using it. I have added the following to my virtual hosts:

SSLVerifyClient optional
SSLVerifyDepth 1
SSLOptions +stdEnvVars

This should allow mod_ssl to get the user's certificate. But I don't know how to pass it along to my django app. Any help is appreciated. Thanks.


Those Apache configuration directives mean that mod_ssl environment variables should now be available in the environment inherited by Django. You can therefore access them using the os.environ object in your Django view:

import os
client_cert = os.environ['SSL_CLIENT_CERT']

The SSL_CLIENT_CERT variable contains the PEM-encoded client certificate.

  • 1
    That will not work if using mod_wsgi although it may work for mod_python, but only because Django does evil things for mod_python adapter and pushed per request environment variables into os.environ on every request. You should just access them from request.META (from memory), which is where per request WSGI environ variables are available. – Graham Dumpleton Sep 23 '11 at 23:31
  • @Graham, thanks. I just finished configuring apache with ssl and noticed that os.environ doesn't contain the 'SSL_CLIENT_CERT' variable. I'll try your solution. – user126284 Sep 24 '11 at 3:35
  • @Graham, using request.META I see a lot of client related stuff, but how do I get the .pem file so that I can sign an XML file with it? Thanks. – user126284 Sep 24 '11 at 4:08
  • Are you seeing any SSL variable in the request.META directory at all? I am not familiar with what SSL_CLIENT_CERT is set to by mod_ssl and what you are trying to do. Can only help you to locate where the variables should be. – Graham Dumpleton Sep 24 '11 at 4:14
  • Yes, I am seeing a lot of variables that start with SSL, such as SSL_SERVER_blah and SSL_CLIENT_blah. I don't know if the .pem file I'm looking for is available to django at all. But thanks anyway. – user126284 Sep 24 '11 at 5:52

You should use

SSLOptions +StdEnvVars
SSLOptions +ExportCertData

in apache config to have SSL_CLIENT_CERT in the environment.

With flask, it will be in request.environ['SSL_CLIENT_CERT']

Based on the discusson of the other answer, it might be request.META['SSL_CLIENT_CERT'] for django.


SSLOptions +StdEnvVars +ExportCertData

SSL_CLIENT_CERT will contain the PEM encoded certificate.

SSL_CLIENT_CERT_CHAIN_n (where n is a number) and SSL_SERVER_CERT are also included, but probably uninteresting.

It's a pity that one can't configure exactly which items you want added to the environment. It would be much more svelte having only what's needed (for me common name and that the verify succeeded - though that may be implied with verify required, and for you the client cert PEM).

Your Answer
