PKI Authentication? How to grab users certificates httpd > wsgi

174 views
Skip to first unread message

LoveWeb2py

unread,
Mar 10, 2015, 2:53:58 PM3/10/15
to web...@googlegroups.com
Hello,

I'm wondering how to get the users details when they visit my site over SSL. I'm guessing I'll have to parse out the information through the WSGI handler? If anyone has insight or could provide direction I'd really appreciate it.

Richard Vézina

unread,
Mar 10, 2015, 3:11:48 PM3/10/15
to web2py-users
Which users details?

On Tue, Mar 10, 2015 at 2:53 PM, LoveWeb2py <atayl...@gmail.com> wrote:
Hello,

I'm wondering how to get the users details when they visit my site over SSL. I'm guessing I'll have to parse out the information through the WSGI handler? If anyone has insight or could provide direction I'd really appreciate it.

--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups "web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web2py+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

LoveWeb2py

unread,
Mar 10, 2015, 3:18:36 PM3/10/15
to web...@googlegroups.com
Just the basic stuff like first name and last name. But when I try to login using the x509 tutorial in the book I am getting Login not allowed. No valid x509 credentials. This tells me that my certificate isn't being read properly by web2py or I'm not passing the variables through uwsgi properly? Do I need to put something in the wsgi-handler, change my httpd.conf, or something else?

Richard Vézina

unread,
Mar 10, 2015, 3:35:17 PM3/10/15
to web2py-users
Is M2Crypto there??

Basic, but you know...

--

Richard Vézina

unread,
Mar 10, 2015, 3:36:53 PM3/10/15
to web2py-users
"This works out of the box with Rocket (the web2py built-in web server) but you may need some extra configuration work on the web server side if you are using a different web server. In particular you need to tell your web server where the certificates are located on local host and that it needs to verify certificates coming from the clients. How to do it is web server dependent and therefore omitted here."

Which server do you use?

Richard


LoveWeb2py

unread,
Mar 10, 2015, 3:37:50 PM3/10/15
to web...@googlegroups.com
Is M2Crypto in my wsgi handler? I have the module installed if that's what you mean.

LoveWeb2py

unread,
Mar 10, 2015, 3:57:12 PM3/10/15
to web...@googlegroups.com
httpd - Apache Hypertext Transfer Protocol Server

my httpd.conf has the certificates and is serving https out properly, I just can't seem to read the user certificates when they visit the site.

LoveWeb2py

unread,
Mar 10, 2015, 4:57:01 PM3/10/15
to web...@googlegroups.com
The main problem is that when I set auth.settings.login_form = X509Auth()  as specified in the book I get the error: Login not allowed. No valid x509 credentials.

My httpd.conf is exactly out of the book as specified for mod_wsgi

http://web2py.com/books/default/chapter/29/13/deployment-recipes#mod_wsgi

I want to pass the certificate credentials to the x509_auth class that web2py has, but its raising an exception because its not finding any certificate present. My browser has certificates in them as I checked them on other sites and they work fine. So its something between the browser, mod_wsgi, wsgi_handler.py or my httpd.conf

Niphlod

unread,
Mar 10, 2015, 5:12:44 PM3/10/15
to web...@googlegroups.com
not everyone needs client certificates, so of course the default config needs tuning.
AFAIK (@michele can chime in any time, he's the original author) what is needed are a few environmental variables passed along, such as

SSL_CLIENT_CERT
SSL_CLIENT_RAW_CERT
SSL_CLIENT_VERIFY
SSL_CLIENT_SERIAL
etc etc etc

Apache docs mention that those should be enabled setting the directive

SSLOptions +stdEnvVars

LoveWeb2py

unread,
Mar 10, 2015, 5:27:57 PM3/10/15
to web...@googlegroups.com
Thanks Niphlod,

I had SSLOptions +stdEnvVars setup, but still no luck. I think that's definitely the problem though (Maybe I'm misplacing them) Hopefully Michele can chyme in.

Niphlod

unread,
Mar 10, 2015, 6:40:29 PM3/10/15
to web...@googlegroups.com
what if you return somewhere this dict (takes the "SSL*" env variables and prints it)

def yourcode():
    .........
    debug_values = {}
    for k, v in request.env.iteritems():
        if k.lower().startswith('ssl'):
            debug_values[k] = v
    .........
    return dict(........., debug_values=debug_values)

just to see if those gets indeed passed along.

LoveWeb2py

unread,
Mar 10, 2015, 7:04:51 PM3/10/15
to web...@googlegroups.com
so I did {{=request.env}} and I can see the SSL DATA certificate in another app, but for some reason the app that requires the data isn't being passed. Going to keep troubleshooting that app because I really want to use the x509 authentication with web2py!!

for some reason the x509 auth isn't working still. Going to keep pressing and will post a fix when I find it. Thank you so much for your help Niphlod. I hope this helps others in the future!

Niphlod

unread,
Mar 10, 2015, 7:56:45 PM3/10/15
to web...@googlegroups.com
debug it, debug it, debug it.

AFAICS, x509_auth.py requires:

ssl_client_raw_cert
optional ssl_client_serial

LoveWeb2py

unread,
Mar 11, 2015, 7:27:46 AM3/11/15
to web...@googlegroups.com
Those are exactly the two I don't have so far from the list I saw in another post I have:

SSL_CIPHER, SSL_CLIENT_I_DN, SSL_CLIENT_CERT, SSL_CLIENT_VERIFY

The following are not being passed (probably a problem with my ssl.conf:
SSL_CLIENT_RAW_CERT, SSL_SESSION_ID, SSL_CLIENT_SERIAL

Almost there! :) I'll post the fix when I find it

Michele Comitini

unread,
Mar 11, 2015, 8:05:48 AM3/11/15
to web...@googlegroups.com
I am glad someone is using x509 Auth, it is a very simple way to handle user security,

One important piece of the puzzle (with apache) is:

SSLVerifyClient optional

The optional allows one to accept any user on the website,  while having  some web2py actions require a valid user certificate
just by adding the standard @auth.requires_login()

 ## Client Authentication (Type):
        # Client certificate verification type and depth. Types are none, optional,
        # require and optional_no_ca. Depth is a number which specifies how deeply
        # to verify the certificate issuer chain before deciding the certificate is
        # not valid.
        #SSLVerifyClient require
        #SSLVerifyDepth  10


LoveWeb2py

unread,
Mar 11, 2015, 8:22:15 AM3/11/15
to web...@googlegroups.com
Thank you so much for posting and for x509 auth. I got it working. For anyone who finds this. If you're using apache you need to change line 33 in x509_auth.py from self.ssl_client_raw_cert = self.request.env.ssl_client_cert

It's the same cert that gets decoded by X509.FORMAT_PEM, but I suspect the ssl_client_raw_cert variable was for NGINX?

Anyways, thank you so much again. The SSLVerifyClient require and SSLVerifyDepth were also a help.

Could you tell me how it works on the backend? How will it create user accounts etc... Some of our users don't have e-mail in their certs so I have that commented out temporarily while I figure something out.

LoveWeb2py

unread,
Mar 11, 2015, 8:39:59 AM3/11/15
to web...@googlegroups.com
Also make sure to have these settings in your virtualhost

SSLEngine On
SSLOptions +stdEnvVars

To verify the variables are being passed properly look at {{=request.env}} in a view and look for SSL variables.

LoveWeb2py

unread,
Mar 11, 2015, 8:48:10 AM3/11/15
to web...@googlegroups.com
Once authentication happens how can I make them members of groups. I notice now they don't have an entry in Auth user. Should I have them register first and once they're reigstered they can use PKI authentication? This is uncharted waters for me so I'm trying to figure out the best approach for it.


On Wednesday, March 11, 2015 at 8:05:48 AM UTC-4, mcm wrote:

Michele Comitini

unread,
Mar 11, 2015, 9:09:07 AM3/11/15
to web...@googlegroups.com
You can read any of the fields a certificate contains eventually.
see here for some ideas: https://code.google.com/p/simpatica/

It's a working PKI that allows to generate csr and sign them with a valid signin certificate

Michele Comitini

unread,
Mar 11, 2015, 9:50:28 AM3/11/15
to web...@googlegroups.com
If you do not have the email you can use the registration_id and username fields.
Most details are on the book: http://web2py.com/books/default/chapter/29/09/access-control

Dave S

unread,
Mar 11, 2015, 1:56:58 PM3/11/15
to web...@googlegroups.com


On Wednesday, March 11, 2015 at 6:50:28 AM UTC-7, mcm wrote:
If you do not have the email you can use the registration_id and username fields.
Most details are on the book: http://web2py.com/books/default/chapter/29/09/access-control

Would it be appropriate to add some of the comments above into the deployment recipe chapter
(#13 , <URL:http://www.web2py.com/books/default/chapter/29/13/deployment-recipes#Apache-setup>
since the X509 section in your link ends with
In particular you need to tell your web server where the certificates are located on local host and that it needs to verify certificates coming from the clients. How to do it is web server dependent and therefore omitted here.


/dps

LoveWeb2py

unread,
Mar 12, 2015, 10:10:33 AM3/12/15
to web...@googlegroups.com
@dps - I agree comments should be added. I'll put together a detailed description of the configuration changes I had to make and the modification needed in x509 auth to get it to work.

-Austin

LoveWeb2py

unread,
Mar 12, 2015, 11:53:00 AM3/12/15
to web...@googlegroups.com
Any thoughts on how I could check to see if the user is a new user and if they are to mark their account as pending (as if I was using the old form of auth). However, pending doesn't seem to work when using x509 auth.

I wanted to use the book class: auth.settings.registration_requires_verification = True

However, if I use PKI authentication it automatically registers the user and grants them access. Any thoughts on how I could set their account to pending when they visit the page for the first time? I was thinking of selecting db(db.auth_user.username==auth.user).select().first() if that equals none then enter their data with the account pending, else just pass, but pending doesn't work either.

Michele Comitini

unread,
Mar 12, 2015, 2:20:50 PM3/12/15
to web...@googlegroups.com
@Austin,
did you try to  set CGI/WSGI variables by using SetEnv and PassEnv directives inside your apache configuration?  IMHO that would make things cleaner than modifying the x509 module.

mic

Michele Comitini

unread,
Mar 12, 2015, 2:43:47 PM3/12/15
to web...@googlegroups.com
You can do another check and raise HTTP(404, 'Pending registration') if the user is pending just after that code you already put in place
Reply all
Reply to author
Forward
0 new messages