Page MenuHomeSoftware Heritage

auth: Add OIDC session silent refresh middleware
ClosedPublic

Authored by anlambert on Mar 25 2020, 2:04 PM.

Details

Summary

When a user has logged in to swh-web from a browser and the access token has expired,
try to perform a silent OIDC session refresh through the use of a Django middleware.

If the OIDC session has expired (idle time reached for instance), a redirection to the
logout page will be performed to inform the user and a link to login again will be
offered.

Related to T2267

Diff Detail

Repository
rDWAPPS Web applications
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

Build is green

Patch application report for D2877 (id=10424)

Rebasing onto 717159e459...

Current branch diff-target is up to date.
Changes applied before test
commit be5880b6778fa8db0f152685cfd4061acd7684c0
Author: Antoine Lambert <antoine.lambert@inria.fr>
Date:   Tue Mar 24 22:11:05 2020 +0100

    auth: Add OIDC session silent refresh middleware
    
    When an access token has expired, try to perform a silent OIDC session
    refresh through the use of a Django middleware.
    
    Closes T2267

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

Sorry I didn't review this sooner, not sure why I didn't see the diff.


What is login_data['prompt']?

swh/web/auth/middlewares.py
34–37

I don't understand: "If the latter failed [...], user will be redirected"

but I don't see a conditional in the code

swh/web/tests/auth/test_middlewares.py
42

that's not a silent refresh

Sorry I didn't review this sooner, not sure why I didn't see the diff.


What is login_data['prompt']?

prompt is a query parameter that can be sent to the OIDC server while attempting to login a user. You can find official OIDC reference below:

prompt
    OPTIONAL. Space delimited, case sensitive list of ASCII string values that specifies whether the Authorization Server prompts the End-User for reauthentication and consent. The defined values are:

        none
            The Authorization Server MUST NOT display any authentication or consent user interface pages. An error is returned if an End-User is not already authenticated or the Client does not have pre-configured consent for the requested Claims or does not fulfill other conditions for processing the request. The error code will typically be login_required, interaction_required, or another code defined in Section 3.1.2.6. This can be used as a method to check for existing authentication and/or consent. 
        login
            The Authorization Server SHOULD prompt the End-User for reauthentication. If it cannot reauthenticate the End-User, it MUST return an error, typically login_required. 
        consent
            The Authorization Server SHOULD prompt the End-User for consent before returning information to the Client. If it cannot obtain consent, it MUST return an error, typically consent_required. 
        select_account
            The Authorization Server SHOULD prompt the End-User to select a user account. This enables an End-User who has multiple accounts at the Authorization Server to select amongst the multiple accounts that they might have current sessions for. If it cannot obtain an account selection choice made by the End-User, it MUST return an error, typically account_selection_required.

I stored this parameter value in django user session in order to know what type of login was performed (initial one with login / password interface displayed or silent session refresh if its value is none).
If the prompt value was none and the OIDC server returns an error, it means corresponding OIDC session has expired and explicit relogin is needed.

For the record, this middleware is inspired from the one that can be found in the mozilla-django-oidc project.

swh/web/auth/middlewares.py
34–37

Indeed, the conditional processing and logout redirection is handled in the oidc-login-complete view as this is the place where we can check if a silent refresh (or relogin) failed or not based on the OIDC server response.

swh/web/tests/auth/test_middlewares.py
42

In practice, it is for a user as no login/password prompt will be displayed if the OIDC session has not expired (i.e. while the refresh token is still valid) .

When a logged user requests a page, the access token will be renewed without user interaction prior redirecting to the requested page, so the silent refresh.

anlambert added inline comments.
swh/web/auth/middlewares.py
34–37

I will update that comment to point to the oidc-login-complete view implementation for a better understanding of that process.

Update:

  • Rebase
  • Modify comment in middleware
  • Fix typo in test variable

Build is green

Patch application report for D2877 (id=10452)

Rebasing onto f9172f8a39...

Current branch diff-target is up to date.
Changes applied before test
commit 6d068f79f1223738569558cdb398b931789e0ac4
Author: Antoine Lambert <antoine.lambert@inria.fr>
Date:   Tue Mar 24 22:11:05 2020 +0100

    auth: Add OIDC session silent refresh middleware
    
    When an access token has expired, try to perform a silent OIDC session
    refresh through the use of a Django middleware.
    
    Closes T2267

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

This revision is now accepted and ready to land.Apr 7 2020, 11:48 AM

Build is green

Patch application report for D2877 (id=10548)

Rebasing onto f77f32dc84...

Current branch diff-target is up to date.
Changes applied before test
commit 05e9efac023a01fd4a7f1971b149affc0d790e9d
Author: Antoine Lambert <antoine.lambert@inria.fr>
Date:   Tue Mar 24 22:11:05 2020 +0100

    auth: Add OIDC session silent refresh middleware
    
    When an access token has expired, try to perform a silent OIDC session
    refresh through the use of a Django middleware.
    
    Closes T2267

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