Page MenuHomeSoftware Heritage

django: Add OIDC Bearer Token authentication backend for DRF views
ClosedPublic

Authored by anlambert on Mar 26 2021, 5:56 PM.

Details

Summary

Add a generic Django REST Framework authentication backend enabling to
authenticate a user using Keycloak and OpenID Connect bearer tokens.

The backend can be easily plugged into a DRF application by:

  • adding "swh.auth.django.backends.OIDCBearerTokenAuthentication" to the REST_FRAMEWORK["DEFAULT_AUTHENTICATION_CLASSES"] django setting.
  • configuring Keycloak URL, realm and client by adding SWH_AUTH_SERVER_URL, SWH_AUTH_REALM_NAME and SWH_AUTH_CLIENT_ID in django settings

Users will then be able to perform authenticated Web API calls by
sending their refresh token in HTTP Authorization headers.

That diff basically moves code and tests from swh-web with slight
changes to make the backend generic.

Related to T3150

Depends on D5365

Diff Detail

Repository
rDAUTH Common authentication libraries
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

Build has FAILED

Patch application report for D5366 (id=19219)

Could not rebase; Attempt merge onto cce5275cc4...

Updating cce5275..a3f1c2a
Fast-forward
 pytest.ini                                         |   1 +
 requirements-django.txt                            |   4 +-
 swh/auth/django/backends.py                        | 200 +++++++++++++++
 swh/auth/django/utils.py                           |  76 +++++-
 swh/auth/django/views.py                           | 152 +++++++++++
 swh/auth/pytest_plugin.py                          |  13 +-
 swh/auth/tests/conftest.py                         |  25 ++
 swh/auth/tests/django/app/apptest/settings.py      |  42 +++
 swh/auth/tests/django/app/apptest/urls.py          |  22 +-
 swh/auth/tests/django/django_asserts.py            |  21 ++
 swh/auth/tests/django/test_backends.py             | 270 ++++++++++++++++++++
 .../tests/django/test_drf_bearer_token_auth.py     | 109 ++++++++
 swh/auth/tests/django/test_utils.py                |   9 +-
 swh/auth/tests/django/test_views.py                | 282 +++++++++++++++++++++
 swh/auth/tests/test_utils.py                       |  36 +++
 swh/auth/utils.py                                  |  35 +++
 16 files changed, 1283 insertions(+), 14 deletions(-)
 create mode 100644 swh/auth/django/backends.py
 create mode 100644 swh/auth/django/views.py
 create mode 100644 swh/auth/tests/conftest.py
 create mode 100644 swh/auth/tests/django/django_asserts.py
 create mode 100644 swh/auth/tests/django/test_backends.py
 create mode 100644 swh/auth/tests/django/test_drf_bearer_token_auth.py
 create mode 100644 swh/auth/tests/django/test_views.py
 create mode 100644 swh/auth/tests/test_utils.py
 create mode 100644 swh/auth/utils.py
Changes applied before test
commit a3f1c2ae354e9aba2384e3f6649609561343c683
Author: Antoine Lambert <antoine.lambert@inria.fr>
Date:   Fri Mar 26 15:04:30 2021 +0100

    django: Add OIDC Bearer Token authentication backend for DRF views
    
    Add a generic Django REST Framework authentication backend enabling to
    authenticate a user using Keycloak and OpenID Connect bearer tokens.
    
    The backend can be easily plugged into a DRF application by:
    
      * adding "swh.auth.django.backends.OIDCBearerTokenAuthentication"
        to the REST_FRAMEWORK["DEFAULT_AUTHENTICATION_CLASSES"]
        django setting.
    
      * configuring Keycloak URL, realm and client by adding
        SWH_AUTH_SERVER_URL, SWH_AUTH_REALM_NAME and SWH_AUTH_CLIENT_ID
        in django settings
    
    Users will then be able to perform authenticated Web API calls by
    sending their refresh token in HTTP Authorization headers.
    
    Related to T3150

commit 0dbac0728e5b7845d27fea5afefda5f0423bc8fd
Author: Antoine Lambert <antoine.lambert@inria.fr>
Date:   Wed Mar 24 17:18:18 2021 +0100

    django: Add OIDC Authorization code PKCE authentication backend
    
    Add a generic Django authentication backend and related login / logout
    views enabling to authenticate a user using Keycloak and the OpenID
    Connect authorization code flow with PKCE ("Proof Key for Code Exchange").
    
    The backend can be easily plugged into any django application by:
    
     - adding "swh.auth.django.backends.OIDCAuthorizationCodePKCEBackend"
       to the AUTHENTICATION_BACKENDS django setting
    
     - configuring Keycloak by adding SWH_AUTH_SERVER_URL, SWH_AUTH_REALM_NAME
       and SWH_AUTH_CLIENT_ID in django settings
    
     - adding swh.auth.django.views.urlpatterns to the django application URLs
    
     - using the dedicated django views: "oidc-login" and "oidc-logout"
    
    Related to T3150

Link to build: https://jenkins.softwareheritage.org/job/DAUTH/job/tests-on-diff/60/
See console output for more information: https://jenkins.softwareheritage.org/job/DAUTH/job/tests-on-diff/60/console

Harbormaster returned this revision to the author for changes because remote builds failed.Mar 26 2021, 5:56 PM
Harbormaster failed remote builds in B20301: Diff 19219!

Build is green

Patch application report for D5366 (id=19221)

Could not rebase; Attempt merge onto cce5275cc4...

Updating cce5275..f3a2391
Fast-forward
 pytest.ini                                         |   1 +
 requirements-django.txt                            |   4 +-
 swh/auth/django/backends.py                        | 200 +++++++++++++++
 swh/auth/django/utils.py                           |  76 +++++-
 swh/auth/django/views.py                           | 152 +++++++++++
 swh/auth/pytest_plugin.py                          |  13 +-
 swh/auth/tests/conftest.py                         |  25 ++
 swh/auth/tests/django/app/apptest/settings.py      |  42 +++
 swh/auth/tests/django/app/apptest/urls.py          |  22 +-
 swh/auth/tests/django/django_asserts.py            |  21 ++
 swh/auth/tests/django/test_backends.py             | 270 ++++++++++++++++++++
 .../tests/django/test_drf_bearer_token_auth.py     | 109 ++++++++
 swh/auth/tests/django/test_utils.py                |   9 +-
 swh/auth/tests/django/test_views.py                | 282 +++++++++++++++++++++
 swh/auth/tests/test_utils.py                       |  36 +++
 swh/auth/utils.py                                  |  35 +++
 16 files changed, 1283 insertions(+), 14 deletions(-)
 create mode 100644 swh/auth/django/backends.py
 create mode 100644 swh/auth/django/views.py
 create mode 100644 swh/auth/tests/conftest.py
 create mode 100644 swh/auth/tests/django/django_asserts.py
 create mode 100644 swh/auth/tests/django/test_backends.py
 create mode 100644 swh/auth/tests/django/test_drf_bearer_token_auth.py
 create mode 100644 swh/auth/tests/django/test_views.py
 create mode 100644 swh/auth/tests/test_utils.py
 create mode 100644 swh/auth/utils.py
Changes applied before test
commit f3a239111669e4146ddc6776a6fbd8308fd454aa
Author: Antoine Lambert <antoine.lambert@inria.fr>
Date:   Fri Mar 26 15:04:30 2021 +0100

    django: Add OIDC Bearer Token authentication backend for DRF views
    
    Add a generic Django REST Framework authentication backend enabling to
    authenticate a user using Keycloak and OpenID Connect bearer tokens.
    
    The backend can be easily plugged into a DRF application by:
    
      * adding "swh.auth.django.backends.OIDCBearerTokenAuthentication"
        to the REST_FRAMEWORK["DEFAULT_AUTHENTICATION_CLASSES"]
        django setting.
    
      * configuring Keycloak URL, realm and client by adding
        SWH_AUTH_SERVER_URL, SWH_AUTH_REALM_NAME and SWH_AUTH_CLIENT_ID
        in django settings
    
    Users will then be able to perform authenticated Web API calls by
    sending their refresh token in HTTP Authorization headers.
    
    Related to T3150

commit 6b6df8f54593715a5986d281bc2835a3c2d70d26
Author: Antoine Lambert <antoine.lambert@inria.fr>
Date:   Wed Mar 24 17:18:18 2021 +0100

    django: Add OIDC Authorization code PKCE authentication backend
    
    Add a generic Django authentication backend and related login / logout
    views enabling to authenticate a user using Keycloak and the OpenID
    Connect authorization code flow with PKCE ("Proof Key for Code Exchange").
    
    The backend can be easily plugged into any django application by:
    
     - adding "swh.auth.django.backends.OIDCAuthorizationCodePKCEBackend"
       to the AUTHENTICATION_BACKENDS django setting
    
     - configuring Keycloak by adding SWH_AUTH_SERVER_URL, SWH_AUTH_REALM_NAME
       and SWH_AUTH_CLIENT_ID in django settings
    
     - adding swh.auth.django.views.urlpatterns to the django application URLs
    
     - using the dedicated django views: "oidc-login" and "oidc-logout"
    
    Related to T3150

See https://jenkins.softwareheritage.org/job/DAUTH/job/tests-on-diff/62/ for more details.

This revision is now accepted and ready to land.Mar 26 2021, 7:13 PM

Update: Only filter on ExpiredSignatureError exception to detect access token expiration.

Build is green

Patch application report for D5366 (id=19294)

Could not rebase; Attempt merge onto cce5275cc4...

Updating cce5275..0c8c3ce
Fast-forward
 mypy.ini                                           |   9 +-
 pytest.ini                                         |   1 +
 requirements-django.txt                            |   4 +-
 swh/auth/django/backends.py                        | 201 +++++++++++++++
 swh/auth/django/utils.py                           |  78 +++++-
 swh/auth/django/views.py                           | 152 +++++++++++
 swh/auth/keycloak.py                               |   7 +-
 swh/auth/pytest_plugin.py                          |  13 +-
 swh/auth/tests/conftest.py                         |  25 ++
 swh/auth/tests/django/app/apptest/settings.py      |  42 +++
 swh/auth/tests/django/app/apptest/urls.py          |  22 +-
 swh/auth/tests/django/django_asserts.py            |  21 ++
 swh/auth/tests/django/test_backends.py             | 256 +++++++++++++++++++
 .../tests/django/test_drf_bearer_token_auth.py     | 109 ++++++++
 swh/auth/tests/django/test_utils.py                |   9 +-
 swh/auth/tests/django/test_views.py                | 282 +++++++++++++++++++++
 swh/auth/tests/test_utils.py                       |  36 +++
 swh/auth/utils.py                                  |  35 +++
 18 files changed, 1283 insertions(+), 19 deletions(-)
 create mode 100644 swh/auth/django/backends.py
 create mode 100644 swh/auth/django/views.py
 create mode 100644 swh/auth/tests/conftest.py
 create mode 100644 swh/auth/tests/django/django_asserts.py
 create mode 100644 swh/auth/tests/django/test_backends.py
 create mode 100644 swh/auth/tests/django/test_drf_bearer_token_auth.py
 create mode 100644 swh/auth/tests/django/test_views.py
 create mode 100644 swh/auth/tests/test_utils.py
 create mode 100644 swh/auth/utils.py
Changes applied before test
commit 0c8c3ce7b9d02708b977352557e5569e286a2f53
Author: Antoine Lambert <antoine.lambert@inria.fr>
Date:   Fri Mar 26 15:04:30 2021 +0100

    django: Add OIDC Bearer Token authentication backend for DRF views
    
    Add a generic Django REST Framework authentication backend enabling to
    authenticate a user using Keycloak and OpenID Connect bearer tokens.
    
    The backend can be easily plugged into a DRF application by:
    
      * adding "swh.auth.django.backends.OIDCBearerTokenAuthentication"
        to the REST_FRAMEWORK["DEFAULT_AUTHENTICATION_CLASSES"]
        django setting.
    
      * configuring Keycloak URL, realm and client by adding
        SWH_AUTH_SERVER_URL, SWH_AUTH_REALM_NAME and SWH_AUTH_CLIENT_ID
        in django settings
    
    Users will then be able to perform authenticated Web API calls by
    sending their refresh token in HTTP Authorization headers.
    
    Related to T3150

commit 367ead11f59ffa7fa8f06e278f3fabc24c254519
Author: Antoine Lambert <antoine.lambert@inria.fr>
Date:   Wed Mar 24 17:18:18 2021 +0100

    django: Add OIDC Authorization code PKCE authentication backend
    
    Add a generic Django authentication backend and related login / logout
    views enabling to authenticate a user using Keycloak and the OpenID
    Connect authorization code flow with PKCE ("Proof Key for Code Exchange").
    
    The backend can be easily plugged into any django application by:
    
     - adding "swh.auth.django.backends.OIDCAuthorizationCodePKCEBackend"
       to the AUTHENTICATION_BACKENDS django setting
    
     - configuring Keycloak by adding SWH_AUTH_SERVER_URL, SWH_AUTH_REALM_NAME
       and SWH_AUTH_CLIENT_ID in django settings
    
     - adding swh.auth.django.views.urlpatterns to the django application URLs
    
     - using the dedicated django views: "oidc-login" and "oidc-logout"
    
    Related to T3150

See https://jenkins.softwareheritage.org/job/DAUTH/job/tests-on-diff/65/ for more details.