-
Notifications
You must be signed in to change notification settings - Fork 113
Description
Hi,
I need to implement the password grant flow between an angular SPA and symfony api back end. My understanding is that I should use the password grant flow. The SPA will serve 3 different brand sites and we will have 3 different OAuth Clients.
The first thing I don't get is since the SPA can't contain the client secret which oauth end point I'll be hitting to get the access token.
Right now we have a two steps registration process and in second step I need to return an access token for the user in order to complete profile. I'm restricting this end point with 'registration' scope and the user will have the role ROLE_USER_INACTIVE + obviously ROLE_OAUTH2_REGISTRATION. So the user can't access anything else. I'm providing the access token like this:
public function getAccessToken(Request $request, Player $player)
{
//Auto wired in constructor
//Nyholm\Psr7\Factory\Psr17Factory $psrHttpFactory,
//League\OAuth2\Server\AuthorizationServer $authorizationServer,
//App\Repository\ClientBrandRepository $clientBrandRepository,
$clientBrand = $this->clientBrandRepository->getOAuthClientByBrand($player->getBrand()->getName());
$request->request->add([
'grant_type' => 'password',
'scope' => 'registration',
'username' => $player->getUsername(),
'password' => 'password',
'client_id' => $clientBrand->getClient()->getIdentifier(),
'client_secret' => $clientBrand->getClient()->getSecret(),
]);
$psrRequest = $this->psrHttpFactory->createRequest($request);
$psr17Factory = new Psr17Factory();
$serverResponse = $psr17Factory->createResponse();
try {
$response = $this->authorizationServer->respondToAccessTokenRequest($psrRequest, $serverResponse);
$responseAsArray = json_decode($response->getBody(), true);
return $responseAsArray;
} catch (OAuthServerException $e) {
return $e->generateHttpResponse($serverResponse);
}
}
Here the password sin't taken into account, here is my UserResolveListener
public function onUserResolve(UserResolveEvent $event): void
{
$user = $this->userBrandProvider->loadPlayerByUsernameClient($event->getUsername(), $event->getClient()->getIdentifier());
if (null === $user) {
return;
}
if ($user->isActive()) {
if (!$this->userPasswordEncoder->isPasswordValid($user, $event->getPassword())) {
return;
}
} else {
if (!$user->isRegistrationOngoing()) {
return;
}
}
$event->setUser($user);
}
Basically in case the user is inactive, I'm checking if the registration is ongoing and without checking the password (since I don't have it) I'm setting the user to the event.
But I'm not using the 2 oauth end points defined in routes/trikoder_oauth2.yaml
oauth2_authorize:
path: /oauth/v2/authorize
defaults: { _controller: Trikoder\Bundle\OAuth2Bundle\Controller\AuthorizationController::indexAction, _method: GET }
oauth2_token:
path: /oauth/v2/token
defaults: { _controller: Trikoder\Bundle\OAuth2Bundle\Controller\TokenController::indexAction, _method: POST }
My question is am I missing something and how I would implement the login? Also since the SPA can't contain the client secret how it would use the refresh token as well?
Thanks