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