Skip to content

Return null from getIdentificationProvider() for identifier-less authenticators#808

Merged
dereuromark merged 3 commits into
4.xfrom
fix-identification-provider-null
Jul 17, 2026
Merged

Return null from getIdentificationProvider() for identifier-less authenticators#808
dereuromark merged 3 commits into
4.xfrom
fix-identification-provider-null

Conversation

@dereuromark

Copy link
Copy Markdown
Member

Fixes #179.

Problem

On 4.x an authenticator's identifier is optional. AuthenticatorCollection::create() passes null when no identifier is configured, and the session authenticator (default identify => false) authenticates purely from stored session data, so it legitimately has no identifier.

AbstractAuthenticator::getIdentifier() throws in that case. AuthenticationService::getIdentificationProvider() called it unconditionally, so the whole request blew up whenever such an authenticator was the successful one:

Identifier is required for `Authentication\Authenticator\SessionAuthenticator`. Please provide an identifier instance.

This surfaces for any consumer that reads the identification provider after a session based login (the reporter hit it via the TinyAuth DebugKit panel).

Fix

  • Add MissingIdentifierException (extends RuntimeException for backwards compatibility) thrown by AbstractAuthenticator::getIdentifier() when no identifier is available.
  • getIdentificationProvider() catches exactly that type and returns null.

Catching the specific type rather than a bare RuntimeException:

  • preserves lazy identifier creation in subclasses (FormAuthenticator, CookieAuthenticator, JwtAuthenticator, TokenAuthenticator, PrimaryKeySessionAuthenticator, ...) whose overridden getIdentifier() builds a default identifier on first call, and
  • does not mask genuine identifier configuration failures, which still throw a plain RuntimeException from IdentifierFactory.

Backwards compatibility

MissingIdentifierException extends RuntimeException, so existing catch (RuntimeException) blocks and the message are unchanged.

…enticators

An authenticator can legitimately operate without an identifier, most notably
the session authenticator with its default `identify` => false: it authenticates
from stored session data and never needs to identify. AbstractAuthenticator's
getIdentifier() throws in that case, so AuthenticationService::
getIdentificationProvider() blew up whenever such an authenticator was the
successful one (e.g. when a DebugKit panel or any consumer read the provider).

Introduce a dedicated MissingIdentifierException (extends RuntimeException for
backwards compatibility) thrown by AbstractAuthenticator::getIdentifier(), and
catch exactly that in getIdentificationProvider() to return null. Catching the
specific type preserves lazy identifier creation in subclasses (Form, Cookie,
Jwt, Token, ...) and does not mask genuine identifier configuration failures,
which still throw a plain RuntimeException from IdentifierFactory.
Comment thread src/Authenticator/MissingIdentifierException.php Outdated

@ADmad ADmad left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM besides the version nitpick.

@dereuromark
dereuromark force-pushed the fix-identification-provider-null branch from bfaeec1 to a8822d5 Compare July 17, 2026 12:21
@dereuromark
dereuromark force-pushed the fix-identification-provider-null branch from a8822d5 to 9c2b90f Compare July 17, 2026 12:22
@dereuromark
dereuromark merged commit 31bf3aa into 4.x Jul 17, 2026
8 checks passed
@dereuromark
dereuromark deleted the fix-identification-provider-null branch July 17, 2026 12:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants