Web Server Authentication Integration (REMOTE_USER) - Mailing list pgadmin-support

From Richard Laager
Subject Web Server Authentication Integration (REMOTE_USER)
Date
Msg-id 6d834f81-5d96-b974-295a-8308ef3170b1@wiktel.com
Whole thread Raw
List pgadmin-support
This is probably essentially a feature request.

I'd like to see pgAdmin 4 support an authentication mechanism where the
username is retrieved from the REMOTE_USER envivonment variable set by
the web server. If the user does not already exist, once should be
created. At no point should the user be prompted with a login form. This
would allow me to integrate with my existing webserver-based login.

Flask already takes REMOTE_USER and exposes it as request.remote_user.

I made several attempts at this, but I just can't quite get it to work.
I'm running on Ubuntu 20.04 with Apache and mod_wsgi. I installed
pgAdmin4 using the .deb/APT packaging from pgadmin.org.

1. I created an authenticate/web.py like this, which ignores the
password and automatically logs in the user with whatever username they
gave, creating them if necessary. This is based off the ldap authentication:

----
"""A blueprint module implementing the webserver authentication."""

import config
from flask_babelex import gettext
from urllib.parse import urlparse

from .internal import BaseAuthentication
from pgadmin.model import User, ServerGroup, db, Role
from flask import current_app
from pgadmin.tools.user_management import create_user


class WebAuthentication(BaseAuthentication):
    """Web Authentication Class"""

    def get_friendly_name(self):
        return gettext("web")

    def authenticate(self, form):
        self.username = form.data['email']
        self.password = form.data['password']
        user_email = None

        return self.__auto_create_user(user_email)

    def __auto_create_user(self, user_email):
        """Add the web user to the internal SQLite database."""
        user = User.query.filter_by(
            username=self.username).first()
        if user is None:
            return create_user({
                'username': self.username,
                'email': user_email,
                'role': 2,
                'active': True,
                'auth_source': 'web'
            })

        return True, None
----

That isn't getting the username from request.remote_user, and I'm not
sure where I'd get a request object in that context. More importantly,
the user still sees a login form.

2. I tried adding the auto-create user code as a request_loader, based
on this:
https://flask-login.readthedocs.io/en/latest/#custom-login-using-request-loader

There I would get an infinite loop where the pgadmin4 root would
redirect me to /login which would redirect me back to the root.

I was just hacking this into create_app(). If I got it working, then a
next step would be to investigate a more appropriate way to integrate
this (e.g. as a plugin or something).

3. I tried converting the desktop login code in create_app() to do this,
but that didn't work:

    @app.before_request
    def before_request():
        """Login the remote user"""

        if not current_user.is_authenticated:
            if not request.remote_user:
                raise Exception("REMOTE_USER not set.")
            user = User.query.filter_by(
                username=request.remote_user).first()
            if user is None:
                from pgadmin.tools.user_management import create_user
                user = create_user({
                    'username': request.remote_user,
                    'email': None,
                    'role': 2,
                    'active': True,
                    'auth_source': 'internal'
                })
            login_user(user)

I tried just running in desktop mode (despite the warnings against
that), but that didn't seem to work either. I get a bunch of
INTERNAL_SERVER_ERROR and the interface does not fully load.

Any thoughts?

-- 
Richard



pgadmin-support by date:

Previous
From: Andrew Sanderson
Date:
Subject: User profile location redirect
Next
From: Patrice LACHANCE
Date:
Subject: Re: PGAdmin integration with IAM authentication