chore(deps): upgrade itk-dev/openid-connect-bundle to 5.0#474
Merged
Conversation
Bumps itk-dev/openid-connect-bundle (and upstream itk-dev/openid-connect) from 4.x to 5.0. The 5.0 release reworks the exception hierarchy around a marker interface: concrete exceptions no longer extend the now-deprecated ItkOpenIdConnectException, so existing `catch (ItkOpenIdConnectException)` blocks would silently match nothing. Migrate the three OIDC catch sites in AuthOidcController and the one in AzureOidcAuthenticator to catch OpenIdConnectExceptionInterface, the new marker that both bundle- and library-thrown exceptions implement. Behaviour (404 unknown provider, 500 OIDC failure, null end-session URL, wrapped auth failure) is unchanged. Add regression tests: - AuthOidcControllerTest: the three getUrls() exception-mapping branches (null end-session URL, 404, 500) that the upgrade put at risk. - AzureOidcAuthenticatorTest: the previously untested authenticate() logic — internal/external user provisioning, group-claim to tenant-role mapping, multi-role accumulation, tenant de-provisioning, and the unknown-suffix / missing-claim / unsupported-provider rejections. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The bundle never set a Guzzle timeout, so calls to the IdP (discovery, JWKS, and especially the un-cached token exchange on the login callback) inherited Guzzle's default of 0 — wait indefinitely. A hung or slow IdP could therefore tie up a php-fpm worker until the FPM request terminator kicked in. itk-dev/openid-connect-bundle 4.2+ exposes http_client_options.timeout (forwarded through league/oauth2-client to Guzzle), but it is opt-in with no default. Set it on both providers via a new OIDC_HTTP_TIMEOUT env var (default 5s), documented in .env and docs/configuration/openid-connect.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tuj
approved these changes
Jun 3, 2026
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.
Summary
Upgrades
itk-dev/openid-connect-bundle(and upstreamitk-dev/openid-connect) from 4.x to 5.0, following both packages'UPGRADE-5.0.mdguides, and closes a long-standing worker-exhaustion risk by bounding the OIDC HTTP calls with an explicit timeout.1. Bundle 5.0 upgrade
The 5.0 release reworks the exception hierarchy around a marker interface: concrete exceptions now extend SPL types and implement
OpenIdConnectExceptionInterface, and no longer extend the deprecatedItkOpenIdConnectException. As a result, the existingcatch (ItkOpenIdConnectException ...)blocks would silently match nothing after the bump — so this is the one thing the upgrade can break.composer.json/composer.lock—itk-dev/openid-connect-bundle: ^5.0; resolves both OIDC packages to 5.0.0.src/Controller/Api/AuthOidcController.php— the twogetUrls()catch sites now catchOpenIdConnectExceptionInterface.src/Security/AzureOidcAuthenticator.php— theauthenticate()catch now usesOpenIdConnectExceptionInterface(which also coversInvalidProviderException).Runtime behaviour is unchanged: 404 for an unknown provider, 500 for an OIDC failure,
endSessionUrl: nullwhen the end-session endpoint isn't configured, and OIDC failures during claim validation wrapped asCustomUserMessageAuthenticationException.2. Explicit OIDC HTTP timeout (worker-exhaustion fix)
The bundle never set a Guzzle timeout, so calls to the IdP inherited Guzzle's default of
0— wait indefinitely. A hung/slow IdP could pin a php-fpm worker. 5.0.0 does not fix this on its own; thehttp_client_options.timeoutknob (added in 4.2.0, forwarded through league/oauth2-client to Guzzle) is opt-in with no default, and this project never set it.config/packages/itkdev_openid_connect.yaml— sethttp_client_options.timeouton both providers..env— newOIDC_HTTP_TIMEOUTenv var, default 5s (passes the env-coverage gate).docs/configuration/openid-connect.md— documented the new var (the README delegates OIDC env-var docs to this file, so no README change needed).Most exposed path: the un-cached token-exchange POST on every login callback is now bounded; the discovery-doc and JWKS fetches (cached 24h) are bounded too on cold cache / refresh. Verified
%env(float:OIDC_HTTP_TIMEOUT)%resolves tofloat(5).Tests
The exception-mapping branches were previously uncovered — nothing in the suite would have caught the silent-catch regression. Added:
AuthOidcControllerTest(3 new) — thegetUrls()branches: null end-session URL (200), unknown provider (404), generic OIDC failure (500).AzureOidcAuthenticatorTest(new file, 8 tests) — the previously untestedauthenticate()logic: internal/external user provisioning, group-claim → tenant-role mapping, multi-role accumulation for one tenant, tenant de-provisioning when claims shrink, and the unknown-role-suffix / missing-id-claim / unsupported-provider rejection paths.task code-analysisclean; 14 OIDC tests / 40 assertions pass.Follow-up (not in this PR)
While testing the tenant-role mapping I found a latent bug in
AzureOidcAuthenticator::getTenantKeyWithRole(): it derives the tenant key withstr_replace('Admin', '', $group)/str_replace('Redaktoer', ...), which strips every occurrence rather than the trailing suffix (e.g.AdminTeamAdmin→Teaminstead ofAdminTeam). Low likelihood (only bites tenant keys containing those substrings) but a real correctness bug in access-control code. Happy to fix it under a separate issue/PR with an anchored suffix removal.🤖 Generated with Claude Code