Skip to content

Commit

Permalink
Added support for OAuth 2 authentication. Fixes #5940
Browse files Browse the repository at this point in the history
Initial patch sent by: Florian Sabonchi
  • Loading branch information
khushboovashi authored and akshay-joshi committed Jul 6, 2021
1 parent fff4060 commit 48ca83f
Show file tree
Hide file tree
Showing 35 changed files with 747 additions and 224 deletions.
1 change: 1 addition & 0 deletions DEPENDENCIES
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ eventlet 0.31.0
httpagentparser 1.9.1 http://www.opensource.org/licenses/mit-license.php http://shon.github.com/httpagentparser
user-agents 2.2.0 MIT https://github.com/selwin/python-user-agents
pywinpty 1.1.1 Unknown Unknown
authlib 0.15.3 BSD https://github.com/lepture/authlib

NOTE: This report was generated using Python 3.9. Full information may not be
shown for Python modules that are not required with this version.
Expand Down
1 change: 1 addition & 0 deletions docs/en_US/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Mode is pre-configured for security.
change_user_password
ldap
kerberos
oauth2


.. note:: Pre-compiled and configured installation packages are available for
Expand Down
Binary file added docs/en_US/images/oauth2_login.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions docs/en_US/kerberos.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ from *config.py* file and modify the values for the following parameters.
Please note that if it is not set, it will take the value of
*default_server* parameter."


Keytab file for HTTP Service
============================

Expand Down Expand Up @@ -116,3 +117,13 @@ PostgreSQL Server settings to configure Kerberos Authentication

* Note that, you have to login into pgAdmin with Kerberos authentication to
then connect to PostgreSQL using Kerberos.


Master Password
===============

In the multi user mode, pgAdmin uses user's login password to encrypt/decrypt the PostgreSQL server password.
In the Kerberos authentication, the pgAdmin user does not have the password, so we need an encryption key to store
the PostgreSQL server password for the servers which are not configured to use the Kerberos authentication.
To accomplish this, set the configuration parameter MASTER_PASSWORD to *True*, so upon setting the master password,
it will be used as an encryption key while storing the password. If it is False, the server password can not be stored.
61 changes: 61 additions & 0 deletions docs/en_US/oauth2.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
.. _oauth2:

*****************************************
`Enabling OAUTH2 Authentication`:index:
*****************************************


To enable OAUTH2 authentication for pgAdmin, you must configure the OAUTH2
settings in the *config_local.py* or *config_system.py* file (see the
:ref:`config.py <config_py>` documentation) on the system where pgAdmin is
installed in Server mode. You can copy these settings from *config.py* file
and modify the values for the following parameters:


.. csv-table::
:header: "**Parameter**", "**Description**"
:class: longtable
:widths: 35, 55

"AUTHENTICATION_SOURCES", "The default value for this parameter is *internal*.
To enable OAUTH2 authentication, you must include *oauth2* in the list of values
for this parameter. you can modify the value as follows:

* [‘oauth2’, ‘internal’]: pgAdmin will display an additional button for authenticating with oauth2"
"OAUTH2_NAME", "The name of the Oauth2 provider, ex: Google, Github"
"OAUTH2_DISPLAY_NAME", "Oauth2 display name in pgAdmin"
"OAUTH2_CLIENT_ID", "Oauth2 Client ID"
"OAUTH2_CLIENT_SECRET", "Oauth2 Client Secret"
"OAUTH2_TOKEN_URL", "Oauth2 Access Token endpoint"
"OAUTH2_AUTHORIZATION_URL", "Endpoint for user authorization"
"OAUTH2_API_BASE_URL", "Oauth2 base URL endpoint to make requests simple, ex: *https://api.github.com/*"
"OAUTH2_USERINFO_ENDPOINT", "User Endpoint, ex: *user* (for github) and *useinfo* (for google)"
"OAUTH2_ICON", "The Font-awesome icon to be placed on the oauth2 button, ex: fa-github"
"OAUTH2_BUTTON_COLOR", "Oauth2 button color"
"OAUTH2_AUTO_CREATE_USER", "Set the value to *True* if you want to automatically
create a pgAdmin user corresponding to a successfully authenticated Oauth2 user.
Please note that password is not stored in the pgAdmin database."

Redirect URL
============

The redirect url to configure Oauth2 server is *http://<pgAdmin Server URL>/oauth2/authorize*

Master Password
===============

In the multi user mode, pgAdmin uses user's login password to encrypt/decrypt the PostgreSQL server password.
In the Oauth2 authentication, the pgAdmin does not store the user's password, so we need an encryption key to store
the PostgreSQL server password.
To accomplish this, set the configuration parameter MASTER_PASSWORD to *True*, so upon setting the master password,
it will be used as an encryption key while storing the password. If it is False, the server password can not be stored.


Login Page
============

After configuration, on restart, you can see the login page with the Oauth2 login button(s).

.. image:: images/oauth2_login.png
:alt: Oauth2 login
:align: center
1 change: 1 addition & 0 deletions docs/en_US/release_notes_5_5.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ New features
| `Issue #1975 <https://redmine.postgresql.org/issues/1975>`_ - Highlighted long running queries on the dashboards.
| `Issue #3893 <https://redmine.postgresql.org/issues/3893>`_ - Added support for Reassign/Drop Owned for login roles.
| `Issue #3920 <https://redmine.postgresql.org/issues/3920>`_ - Do not block the query editor window when running a query.
| `Issue #5940 <https://redmine.postgresql.org/issues/5940>`_ - Added support for OAuth 2 authentication.
| `Issue #6559 <https://redmine.postgresql.org/issues/6559>`_ - Added option to provide maximum width of the column when 'Resize by data?’ option in the preferences is set to True.
Housekeeping
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@ eventlet==0.31.0
httpagentparser==1.9.*
user-agents==2.2.0
pywinpty==1.1.1; sys_platform=="win32"
Authlib==0.15.*
requests==2.25.*
48 changes: 45 additions & 3 deletions web/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,10 +562,11 @@
##########################################################################

# Default setting is internal
# External Supported Sources: ldap, kerberos
# External Supported Sources: ldap, kerberos, oauth2
# Multiple authentication can be achieved by setting this parameter to
# ['ldap', 'internal']. pgAdmin will authenticate the user with ldap first,
# in case of failure internal authentication will be done.
# ['ldap', 'internal'] or ['oauth2', 'internal'] etc.
# pgAdmin will authenticate the user with ldap/oauth2 whatever first in the
# list, in case of failure the second authentication option will be considered.

AUTHENTICATION_SOURCES = ['internal']

Expand Down Expand Up @@ -666,6 +667,47 @@

KERBEROS_CCACHE_DIR = os.path.join(DATA_DIR, 'krbccache')

##########################################################################
# OAuth2 Configuration
##########################################################################

# Multiple OAUTH2 providers can be added in the list like [{...},{...}]
# All parameters are required

OAUTH2_CONFIG = [
{
# The name of the of the oauth provider, ex: github, google
'OAUTH2_NAME': None,
# The display name, ex: Google
'OAUTH2_DISPLAY_NAME': '<Oauth2 Display Name>',
# Oauth client id
'OAUTH2_CLIENT_ID': None,
# Oauth secret
'OAUTH2_CLIENT_SECRET': None,
# URL to generate a token,
# Ex: https://github.com/login/oauth/access_token
'OAUTH2_TOKEN_URL': None,
# URL is used for authentication,
# Ex: https://github.com/login/oauth/authorize
'OAUTH2_AUTHORIZATION_URL': None,
# Oauth base url, ex: https://api.github.com/
'OAUTH2_API_BASE_URL': None,
# Name of the Endpoint, ex: user
'OAUTH2_USERINFO_ENDPOINT': None,
# Font-awesome icon, ex: fa-github
'OAUTH2_ICON': None,
# UI button colour, ex: #0000ff
'OAUTH2_BUTTON_COLOR': None,
}
]

# After Oauth authentication, user will be added into the SQLite database
# automatically, if set to True.
# Set it to False, if user should not be added automatically,
# in this case Admin has to add the user manually in the SQLite database.

OAUTH2_AUTO_CREATE_USER = True

##########################################################################
# PSQL tool settings
##########################################################################
Expand Down
21 changes: 14 additions & 7 deletions web/pgadmin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,13 @@
from pgadmin.utils.csrf import pgCSRFProtect
from pgadmin import authenticate
from pgadmin.utils.security_headers import SecurityHeaders
from pgadmin.utils.constants import KERBEROS
from pgadmin.utils.constants import KERBEROS, OAUTH2, INTERNAL, LDAP

# Explicitly set the mime-types so that a corrupted windows registry will not
# affect pgAdmin 4 to be load properly. This will avoid the issues that may
# occur due to security fix of X_CONTENT_TYPE_OPTIONS = "nosniff".
import mimetypes

mimetypes.add_type('application/javascript', '.js')
mimetypes.add_type('text/css', '.css')

Expand Down Expand Up @@ -469,6 +470,13 @@ def upgrade_db():
'SECURITY_EMAIL_VALIDATOR_ARGS': config.SECURITY_EMAIL_VALIDATOR_ARGS
}))

app.config.update(dict({
'INTERNAL': INTERNAL,
'LDAP': LDAP,
'KERBEROS': KERBEROS,
'OAUTH2': OAUTH2
}))

security.init_app(app, user_datastore)

# register custom unauthorised handler.
Expand Down Expand Up @@ -760,19 +768,18 @@ def before_request():
)
abort(401)
login_user(user)
elif config.SERVER_MODE and\
app.PGADMIN_EXTERNAL_AUTH_SOURCE ==\
KERBEROS and \
elif config.SERVER_MODE and \
not current_user.is_authenticated and \
request.endpoint in ('redirects.index', 'security.login'):
return authenticate.login()

if app.PGADMIN_EXTERNAL_AUTH_SOURCE == KERBEROS:
return authenticate.login()
# if the server is restarted the in memory key will be lost
# but the user session may still be active. Logout the user
# to get the key again when login
if config.SERVER_MODE and current_user.is_authenticated and \
app.PGADMIN_EXTERNAL_AUTH_SOURCE != \
KERBEROS and \
KERBEROS and app.PGADMIN_EXTERNAL_AUTH_SOURCE != \
OAUTH2 and\
current_app.keyManager.get() is None and \
request.endpoint not in ('security.login', 'security.logout'):
logout_user()
Expand Down
Loading

0 comments on commit 48ca83f

Please sign in to comment.