Skip to content

Document AuthenticatorInterface DI binding requirement for autowired Authentication middleware - #127

Open
rossaddison wants to merge 5 commits into
yiisoft:masterfrom
rossaddison:docs/di-container-authenticator-binding
Open

Document AuthenticatorInterface DI binding requirement for autowired Authentication middleware#127
rossaddison wants to merge 5 commits into
yiisoft:masterfrom
rossaddison:docs/di-container-authenticator-binding

Conversation

@rossaddison

Copy link
Copy Markdown
Q A
Is bugfix?
New feature?
Breaks BC?
Fixed issues

Summary

Authentication's constructor requires AuthenticatorInterface, and the package ships no default
implementation for a container to autowire it to. That's fine when it's constructed manually (as the
existing "General usage" example shows), but when a framework builds the middleware via autowiring instead —
applying it to a route by class name, as yiisoft/router groups commonly do
(->middleware(Authentication::class)) — an unbound AuthenticatorInterface fails with a message that never
names the actual gap:

No definition or class found for "Yiisoft\Auth\Middleware\Authentication" ID.
No definition or class found or resolvable for "Yiisoft\Auth\AuthenticatorInterface"
while building "Yiisoft\Auth\Middleware\Authentication" -> "Yiisoft\Auth\AuthenticatorInterface".

We hit this for real in a production Yii3 app after adopting 3.3.0's AuthenticatorInterface split
(#113/#115): the middleware had been referenced via autowiring across most of the app's routes with no
binding ever configured — it had simply never actually been constructed until a compiled DI container cache
was invalidated by an unrelated composer update, at which point every one of those routes started 500ing.

This PR adds a short "Using with a DI container" section to the README documenting the binding requirement,
with an example, and explicitly naming the equally valid alternative when a route doesn't need
HTTP-challenge-style authentication at all: don't apply this middleware there, rather than binding an
authenticator you don't otherwise use just to satisfy the container.

Related write-up

For anyone wanting the fuller story (including the exact production exception, the fix, and a plain-English
explainer on when an app would actually need WWW-Authenticate-style auth vs. session-based login):
https://github.com/rossaddison/invoice/blob/main/docs/AUTHENTICATION_DI_CRASH_FIX_AUGUST_2026.md and
https://github.com/rossaddison/invoice/blob/main/docs/WWW_AUTHENTICATE_VS_SESSION_AUTH_AUGUST_2026.md
(the latter also has Persian/Portuguese translations, if useful to anyone on the team or in the wider
community).

Happy to adjust wording/placement if you'd rather this live in docs/internals.md instead, or if you'd
prefer the constructor itself to throw a more specific exception rather than (or in addition to) documenting
it — from what I can tell the current message actually originates in yiisoft/di's generic resolution
failure, not in this package, so a code-level fix may not be in scope here at all.

Authentication's constructor requires AuthenticatorInterface, with no
default implementation for a container to autowire it to. When a
framework builds the middleware via autowiring rather than manual
construction (e.g. applying it to a route by class name, as
yiisoft/router groups commonly do), an unbound AuthenticatorInterface
fails with a message that never names the actual gap:

    No definition or class found for "Yiisoft\Auth\Middleware\Authentication" ID.
    No definition or class found or resolvable for "Yiisoft\Auth\AuthenticatorInterface"
    while building "Yiisoft\Auth\Middleware\Authentication" -> "Yiisoft\Auth\AuthenticatorInterface".

Hit for real in a production Yii3 app after adopting 3.3.0's
AuthenticatorInterface split: the middleware had been referenced via
autowiring across most of the app's routes with no binding ever
configured, working only because it had never actually been
constructed until a compiled DI container cache was invalidated by an
unrelated composer update.

New "Using with a DI container" README section documents the binding
requirement with an example, and calls out the equally valid
alternative when a route doesn't need HTTP-challenge-style
authentication at all: don't apply this middleware there, rather than
binding an authenticator you don't otherwise use just to satisfy the
container.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3661e087-e1db-4542-b0c8-24690a076cbc

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread CHANGELOG.md Outdated
Comment thread README.md
Comment thread README.md
@rossaddison

Copy link
Copy Markdown
Author

For anyone curious what applying this pattern actually looks like end-to-end in the same app that hit
the original DI issue: rossaddison/invoice#1038 migrates one real endpoint (an external cron scheduler's
HTTP trigger, previously secured by a hand-checked URL query parameter) to real Bearer-token auth using
this package — AuthenticatorInterface bound to HttpBearer, Authentication middleware applied to
just that one route, verified live (401 + WWW-Authenticate: Bearer realm="api" on a missing/wrong
token, 200 on a valid one). Writeup: https://github.com/rossaddison/invoice/blob/main/docs/INVRECURRING_CRON_BEARER_AUTH_AUGUST_2026.md

@samdark
samdark requested review from vjik and a lite review from Copilot August 9, 2026 21:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the documentation to clarify that when Yiisoft\Auth\Middleware\Authentication is constructed via DI/autowiring, the DI container must be configured with a binding for Yiisoft\Auth\AuthenticatorInterface, otherwise middleware resolution fails.

Changes:

  • Add a “Using with a DI container” section to the README.
  • Provide an example DI definition intended to bind AuthenticatorInterface to a concrete authenticator implementation.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread README.md
Comment on lines +59 to +71
e.g. recurring invoice monthly cron

```php
use App\Invoice\InvRecurring\CronTokenRepository;
use Yiisoft\Auth\AuthenticatorInterface;
use Yiisoft\Auth\Method\HttpBearer;

return [
AuthenticatorInterface::class => static fn (CronTokenRepository $cronTokenRepository): HttpBearer =>
new HttpBearer($cronTokenRepository),
];

```
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.

3 participants