Description
Q | A |
---|---|
Bug report? | yes |
Feature request? | no |
BC Break report? | no |
RFC? | no |
Symfony version | 3.3 (dev-master) |
I've been playing around with the new feature @dunglas introduced in PR-18952 and think I've come across a discrepancy in how the token is set in an application when using json_login
vs. form_login
configurations.
TL;DR The token set by a call to $this->tokenStorage->setToken($token);
in UsernamePasswordJsonAuthenticationListener.php#L119 assigns the initial token created which has a string-based user representation whereas the token set by the UsernamePasswordFormAuthenticationListener AbstractAuthenticationListener.php#L219 uses the resulting authenticated token from the call to the authenticate
method on the authentication manager.
I am using the json_login
feature to integrate with the LexikJWTAuthenticationBundle, and discovered this discrepancy after receiving an error wherein the aforementioned bundle was objecting to one of the arguments being a string instead of an object implementing UserInterface
.
Whether the JWT bundle I'm using should is correct or incorrect in its expectations is a valid question in and of itself, this led me down the proverbial rabbit hole. Down there I noticed that the token returned by DaoAuthenticationProvider
at: UserAuthenticationProvider.php#L96 is not being used by the UsernamePasswordJsonAuthenticationListener
. Instead it is using the $token
that the was instantiated to perform the original authentication request was made with.
Comparing the above with the behavior of the UsernamePasswordFormAuthenticationListener
, the authentication is attempted with a new UsernamePasswordToken
, using the values derived from the login request (see: UsernamePasswordFormAuthenticationListener.php#L93), but once the authentication has been attempted and a result returned from the call to authenticate
, the token returned by the provider is the $token
sent to the onSuccess
method, see: AbstractAuthenticationListener.php#L153.
Is this discrepancy intentional?
It seems like changing the behavior of the UsernamePasswordJsonAuthenticationListener
to something like:
public function handle(GetResponseEvent $event)
{
...
try {
$token = new UsernamePasswordToken($username, $password, $this->providerKey);
$returnValue = $this->authenticationManager->authenticate($token);
if (null === $returnValue) {
return;
}
if ($returnValue instanceof TokenInterface) {
$response = $this->onSuccess($request, $returnValue);
}
} catch (AuthenticationException $e) {
$response = $this->onFailure($request, $e);
}
$event->setResponse($response);
}
Would at least make the behavior of the two firewalls more similar.