Allow signing in to the UI through the NDP identity provider#194
Merged
Conversation
added 4 commits
July 20, 2026 03:19
Users who authenticate through a federated provider configured in the realm (CILogon, EarthScope, ORCID) have no password in the realm, so the username/password form cannot work for them. Their only route in was to sign in on nationaldataplatform.org, find their access token and paste it by hand. Add a third way in that sends the user to the identity provider's own login page, where those providers are offered. The Authorization Code flow with PKCE is used against a public client, so no client secret has to be shipped with the Endpoint. The resulting token is handed to the existing setAndValidateToken path, so validation, storage and the access-denied (403) request-access flow behave exactly as they do for the other methods. The button is rendered only when OIDC_ISSUER and OIDC_CLIENT_ID are both set; deployments that leave them empty are unchanged. PKCE needs crypto.subtle, which browsers expose only in secure contexts, so over plain http the button is disabled with an explanation rather than silently downgrading to the weaker plain challenge method. Refs #193
After the identity provider authenticated the user, any non-403 failure was surfaced through the shared "Invalid token: Authentication failed" wording, which reads as mistyped credentials. It is not: the sign-in succeeded and the Endpoint could not validate the resulting token. Seen in practice when the client mints tokens without a `sub` claim: AUTH_API_URL looks the user up by `sub`, returns 500, and the Endpoint turns that into a 401. Document the claim as a client requirement so the next deployment does not have to diagnose it from scratch. Refs #193
Put the feature behind OIDC_ENABLED, defaulting to False, so a deployment that says nothing keeps the login screen it already had. Switching it on without OIDC_ISSUER and OIDC_CLIENT_ID shows no button rather than one that fails the moment it is clicked. Move the button wording out of the build. It named the National Data Platform and its three federated providers, which is wrong for any other realm and for a realm that has none configured. OIDC_BUTTON_LABEL and OIDC_HELP_TEXT now supply it, defaulting to provider-neutral wording and to no second line at all, since only the deployment knows what its realm offers. Nothing about a particular identity provider is left in the build: the endpoints come from the realm's discovery document and the callback URL is derived from the browser's address and ROOT_PATH, so moving from a local Keycloak to production is a change of OIDC_ISSUER. Document the whole thing in example.env and docs/configuration.md, including what the identity provider administrator has to register and the two failure modes that cost real time to diagnose: a client that mints tokens without a sub claim, and OIDC_ISSUER disagreeing with AUTH_API_URL. Refs #193
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #193
What this adds
A third way into the UI: a button that sends the user to the identity provider's own login page, where the federated providers configured on the realm (CILogon, EarthScope, ORCID) are offered.
This matters because users arriving with institutional credentials have no password in the realm, so the username/password form never worked for them. Their only route in was to sign in on nationaldataplatform.org, find their access token and paste it by hand.
The access token and username/password methods are unchanged and remain available.
How it works
OAuth Authorization Code flow with PKCE (S256) against a public client, so no client secret has to be distributed with the Endpoint, which is self-hosted by many institutions. The resulting token is handed to the existing
setAndValidateTokenpath, so validation, storage and the access-denied (403) request-access flow behave exactly as they do for the other methods.Configuration
Off by default. Existing deployments are unaffected until they opt in.
OIDC_ENABLEDFalseOIDC_ISSUEROIDC_CLIENT_IDOIDC_SCOPEopenid profile emailOIDC_BUTTON_LABELSign in with your identity providerOIDC_HELP_TEXTNothing about a particular identity provider is baked into the build: endpoints come from the realm's OpenID discovery document, the callback URL is derived from the browser's address and
ROOT_PATH, and the button wording is deployment-supplied. Moving from a local Keycloak to production is a change ofOIDC_ISSUER.Switching it on without both
OIDC_ISSUERandOIDC_CLIENT_IDrenders no button, rather than one that fails on click.Verified
Tested end to end against a Keycloak realm: sign-in on the provider's page, callback, PKCE code exchange, token validation via
AUTH_API_URL, and/user/inforeturning the user's real roles and groups.black --checkandflake8cleanApp.test.jsfails on this branch, but it fails identically onmain— it is a pre-existing module-resolution problem, untouched here.Notes for reviewers
Two failure modes cost real time to diagnose and are now documented in
example.envanddocs/configuration.md:subclaim.AUTH_API_URLlooks the user up bysub. Since Keycloak 24 that claim comes from the built-inbasicclient scope, and a realm imported from an older export may not have it among its default scopes — so a freshly created client silently issues tokens withoutsuband sign-in fails at the last step.OIDC_ISSUERandAUTH_API_URLpointing at different identity providers. The token is minted by one and validated by the other; if they disagree the user'ssubdoes not exist on the validating side.PKCE needs
crypto.subtle, which browsers expose only in secure contexts. On a plain-http or bare-IP deployment the button is shown disabled with an explanation rather than silently downgrading to the weakerplainchallenge method; the other two sign-in methods still work there.