0

How to use Python3 cgi for Http, Https basic authentication in Apache instead of a htpasswd file?

I'm trying to get my authentication info from a database instead of htpasswd files, but still use the Apache authentication basic asking for the username, password, how do I use python3 to do this?

Stan S.
  • 237
  • 7
  • 22

1 Answers1

0

Ok, I've been a huge fan of Python3 cgi for web programming for quite some time now. As my Python3 cgi arrows in the quiver continue to grow, the 1) How to include external python file, and 2) Running Python scripts like PHP in Apache, and 3) Output, print UTF-8 html with enc_print()

this should be another good technique to use.

This is how to use Python3 cgi for HTTP, HTTPS basic authentication in Apache.

In Debian/Ubuntu/Linux Mint install the authnz-external Apache module:

sudo apt-get install libapache2-mod-authnz-external

Second, enable the module

a2enmod authnz_external

Then restart Apache

sudo systemctl restart apache2

Here's an example script to test the credentials in Python3 myauth.py

#!/usr/bin/python3

import sys

from html import escape

username = ''
password = ''
args = []
auth = False

for line in sys.stdin:
    args.append( escape(line.rstrip()) )

if (len(args) == 2):
    username = args[0]
    password = args[1]

    if (username == 'user1' and password == 'mypassword'):
        auth = True
        
if (auth):    
    exit(0) # login successful
else:
    exit(1) # login fail

Basically, the script is reading from stdin and checks the username and password, and then returns an exit status codes; 0 means OK, and anything else means NOT OK.

The script needs to be executable.

chmod +x myauth.py

Next, configure your Apache conf Define an ExternalAuth directive in for example /etc/apache2/conf.d/authnz_external.conf

# define pyauth for authentication
DefineExternalAuth pyauth pipe /path/to/script/myauth.py

Then in a VirtualHost block of a site you need to provide the AuthBasicProvider and AuthExternal directive. For example, to protect the location /secure on your website:

<Location /secure>
        AuthType Basic
        AuthName "Authentication required"
        AuthBasicProvider external
        AuthExternal pyauth
        Require valid-user
</Location>

With the Python3 script you could modify the script to query a mysql / postgresql (recommended) database for the username and password.

Just note that, if you are accessing your site with https using for example letsencrypt the username and password will be sent securely to Apache's basic authentication and to the Python3 script for authentication.

Finally, restart Apache again and test your configuration.

Stan S.
  • 237
  • 7
  • 22