Problem/Motivation
Part of #3630879: Allow OAuth2 clients that are not saved consumer entities
TokenAuthUser::__construct() loads the consumer from $token->get('client')->entity and uses it twice:
- As the fallback subject: when the token has no
auth_user_id (client credentials), it uses the consumer's user_id.
- For
getConsumer(). Its only caller is SimpleOauthAuthenticationProvider::authenticate(), which sets the X-Consumer-ID request header for the Consumers negotiator.
The OAuth flows get their client from simple_oauth.repositories.client. This is the one lookup during request authentication that bypasses it, and it runs on every authenticated request.
Proposed resolution
- Inject
simple_oauth.repositories.client into SimpleOauthAuthenticationProvider.
- Resolve the client with
getClientEntity($token->get('client_id')->value) and pass it to TokenAuthUser. Throw OAuthServerException::invalidClient() when it returns NULL.
- Add
TokenAuthUser::getClient(): ClientEntityInterface.
- Deprecate
TokenAuthUser::getConsumer() and have it return $this->getClient()->getDrupalEntity().
- Set
X-Consumer-ID from getClient()->getIdentifier().
The Consumers negotiator still loads consumers by client_id from storage. Clients served by another repository won't resolve there. That belongs in the Consumers queue, not here.
Remaining tasks
- MR with a kernel test that decorates
ClientRepository and authenticates a request.
- Change record for the deprecation.
API changes
- New:
TokenAuthUser::getClient().
- Deprecated:
TokenAuthUser::getConsumer().
- The
TokenAuthUser constructor signature changes. It's built only by SimpleOauthAuthenticationProvider.
AI disclosure
AI-Generated: Yes. I drafted this issue summary with Claude Code and reviewed it before filing.
Comments
Comment #2
mglamanComment #3
vidit.anjaria commented