IQSS / dataverse-frontend

An upcoming and modernized UI for Dataverse
Apache License 2.0
20 stars 16 forks source link

OIDC integration PoC #516

Open GPortas opened 1 month ago

GPortas commented 1 month ago

What this PR does / why we need it:

This PR establishes a PoC for the new OIDC authentication, following the approach of using an OIDC-PKCE library on the client side (SPA) for user login and tokens retrieval, and the existing BearerTokenAuthMechanism (with some minor modifications) on the server side for API auth.

Changes in the SPA

We are using https://www.npmjs.com/package/react-oauth2-code-pkce, which is a lightweight package that easily integrates our SPA with an OIDC identity provider using PKCE. The library syncs with the OIDC provider to manage token refresh and expiration, as well as allowing us to restrict access to certain routes based on whether they are protected or not.

We have added a containerized Keycloak to the dev-env network with some pre-created built-in users to test the flow. Nginx reverse proxy remains the only entry point for the users (port 8000) but now redirecting authentication-related routes to the Keycloak instance.

Changes in js-dataverse

In js-dataverse, we have implemented a new authentication mechanism to send the generated bearer token (after successful OIDC login) in each API request. This implementation is very simple (~10 lines of code), since the package easily allows extending new authentication mechanisms as required.

The changes are implemented in this PR: https://github.com/IQSS/dataverse-client-javascript/pull/201 (The PR generated npm tag is used in the SPA)

Changes in Dataverse

The only changes made on the Dataverse side involve the current BearerTokenAuthMechanism. Specifically, we have enabled the creation of users when a valid bearer token is sent, but does not correspond to an existing Dataverse user.

Now in such case, the user is created within the BearerTokenAuthMechanism, transparently to the calling user, ensuring that this user exists in Dataverse for subsequent requests for that calling user.

The changes are present in this PR: https://github.com/IQSS/dataverse/pull/10910

These changes are not intended to be final; given that this is a PoC, the implementation may appear somewhat rough. The information needed to create the user is extracted from the JWT itself, as Keycloak includes the necessary claims for user identification. However, as noted in a TODO comment within the PR, it will be necessary to supplement this information—possibly by calling the IdP—when the claims are insufficient for identification.

Demo

https://github.com/user-attachments/assets/a54bc525-1212-4e8d-ac35-67aa8b00baed

Suggestions on how to test this:

1) Make sure your dev-env/.env file is filled with the appropriate data. For the REGISTRY variable, please set ghcr.io, as we will use a PR-generated dataverse image.

2) Navigate with cd packages/design-system && npm run build to build the design system.

3) Now you can run the entire PoC by navigating with cd dev-env simply executing the following command:

./run-env.sh poc-oidc-spa-integration

OIDC login credentials

Aditional resources

Diagram from the auth redesign docs

Screenshot 2024-10-15 at 13 57 53

PoC diagram

Screenshot 2024-10-15 at 13 57 53
coveralls commented 1 month ago

Coverage Status

coverage: 98.403% (+1.2%) from 97.179% when pulling 882fbb9050be1ebfd9d36b3e0a15ec55132874d4 on poc/oidc_pkce into ac7e2fcab3a27f870c210d78a59dbe342ca948e0 on develop.