TOMEE-4648 - BASIC mechanism rejects valid credentials with an application IdentityStore#2851
TOMEE-4648 - BASIC mechanism rejects valid credentials with an application IdentityStore#2851jungm wants to merge 1 commit into
Conversation
The BASIC mechanism passed a BasicAuthenticationCredential to IdentityStoreHandler.validate(Credential). The spec's default IdentityStore.validate(Credential) dispatches to a validate(...) overload only on an exact parameter-type match, and BasicAuthenticationCredential is a subclass of UsernamePasswordCredential, so an application store declaring the idiomatic validate(UsernamePasswordCredential) overload was never invoked and returned NOT_VALIDATED - producing a 401 for valid credentials. Built-in stores were unaffected, so it only surfaced with an application-supplied IdentityStore. Hand the identity store a plain UsernamePasswordCredential (reusing the already-parsed Password) while still parsing the header via BasicAuthenticationCredential. Adds a test mirroring the TCK app-mem-basic identity store.
|
Diagnosis is right and matches the RI — Soteria's Three things before merge:
Follow-up JIRA worth filing: |
What
Fixes TOMEE-4648: the BASIC authentication mechanism answered
401for valid credentials when validation went against an application-suppliedIdentityStore.Why
BasicAuthenticationMechanismpassed aBasicAuthenticationCredentialtoIdentityStoreHandler.validate(Credential). The spec's defaultIdentityStore.validate(Credential)dispatches to avalidate(...)overload only on an exact parameter-type match — its javadoc states explicitly that it does not look for the most specific overload. SinceBasicAuthenticationCredential extends UsernamePasswordCredential, a store declaring the idiomaticvalidate(UsernamePasswordCredential)overload (exactly what the Jakarta Security TCK'sTestIdentityStoredoes) was never invoked and returnedNOT_VALIDATED, producing a 401.Built-in stores (e.g. Tomcat users) declare their own credential handling and were unaffected, which is why this only surfaced with an application store — and why the plain, decorated, and custom-handler TCK variants all failed the same
testAuthenticatedcheck.Change
BasicAuthenticationMechanism.validateRequeststill parses theAuthorizationheader viaBasicAuthenticationCredential(which does the base64 decoding), but now hands the identity store a plainUsernamePasswordCredential, reusing the already-parsedPassword(no plaintext round-trip). The empty/malformed-header path is unchanged — the constructor still throwsIllegalArgumentException, caught as before to fall through to the challenge.Tests
Tomee4648BasicGroupsTestmirrors the TCKapp-mem-basicmodule (an@ApplicationScoped IdentityStorewith only thevalidate(UsernamePasswordCredential)overload). It fails with 401 before the change and passes after, asserting caller name and both groups.tomee-securitymodule is green (108 tests), including the existing BASIC negative cases (wrong password, unknown user, missing role).TCK impact
Removes the cause of these exclusions in the apache/tomee-tck
securityrunner:AppMemBasicIT#testAuthenticatedAppMemBasicDecorateIT#testAuthenticatedAppCustomAuthenticationMechanismHandler2ITNote for reviewers
The two OpenID TCK modules originally bundled into TOMEE-4648 were not a TomEE bug — they were a test-harness environment issue (the bundled OpenID provider's
startup.shneedsJAVA_HOME, which was unset). Both pass unchanged onceJAVA_HOMEis set; that fix lives in apache/tomee-tck and is out of scope for this PR. The ticket has been updated accordingly.🤖 Generated with Claude Code