/** * {@inheritdoc} */ public function respondToAccessTokenRequest(ServerRequestInterface $request, ResponseTypeInterface $responseType, \DateInterval $accessTokenTTL) { // Validate request $client = $this->validateClient($request); $scopes = $this->validateScopes($this->getRequestParameter('scope', $request)); // Finalize the requested scopes $scopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client); // Issue and persist access token $accessToken = $this->issueAccessToken($accessTokenTTL, $client, null, $scopes); // Inject access token into response type $responseType->setAccessToken($accessToken); return $responseType; }
/** * Get the token type that grants will return in the HTTP response. * * @return ResponseTypeInterface */ protected function getResponseType() { if ($this->responseType instanceof ResponseTypeInterface === false) { $this->responseType = new BearerTokenResponse(); } $this->responseType->setPrivateKey($this->privateKey); return $this->responseType; }
/** * {@inheritdoc} */ public function respondToAccessTokenRequest(ServerRequestInterface $request, ResponseTypeInterface $responseType, DateInterval $accessTokenTTL) { // Validate request $client = $this->validateClient($request); $scopes = $this->validateScopes($this->getRequestParameter('scope', $request)); // Finalize the requested scopes $scopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client); $userIdentifier = $this->getRequestParameter('user_id', $request); if (is_null($userIdentifier)) { throw OAuthServerException::invalidRequest('user_id'); } $this->tokenName = $this->getRequestParameter('token_name', $request); if (is_null($this->tokenName)) { throw OAuthServerException::invalidRequest('token_name'); } // Issue and persist access token $accessToken = $this->issueAccessToken(new DateInterval('P5Y'), $client, $userIdentifier, $scopes); // Inject access token into response type $responseType->setAccessToken($accessToken); return $responseType; }
/** * {@inheritdoc} */ public function respondToAccessTokenRequest(ServerRequestInterface $request, ResponseTypeInterface $responseType, \DateInterval $accessTokenTTL) { // Validate request $client = $this->validateClient($request); $oldRefreshToken = $this->validateOldRefreshToken($request, $client->getIdentifier()); $scopes = $this->validateScopes($this->getRequestParameter('scope', $request)); // If no new scopes are requested then give the access token the original session scopes if (count($scopes) === 0) { $scopes = array_map(function ($scopeId) use($client) { $scope = $this->scopeRepository->getScopeEntityByIdentifier($scopeId); if ($scope instanceof ScopeEntityInterface === false) { // @codeCoverageIgnoreStart throw OAuthServerException::invalidScope($scopeId); // @codeCoverageIgnoreEnd } return $scope; }, $oldRefreshToken['scopes']); } else { // The OAuth spec says that a refreshed access token can have the original scopes or fewer so ensure // the request doesn't include any new scopes foreach ($scopes as $scope) { if (in_array($scope->getIdentifier(), $oldRefreshToken['scopes']) === false) { throw OAuthServerException::invalidScope($scope->getIdentifier()); } } } // Expire old tokens $this->accessTokenRepository->revokeAccessToken($oldRefreshToken['access_token_id']); $this->refreshTokenRepository->revokeRefreshToken($oldRefreshToken['refresh_token_id']); // Issue and persist new tokens $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $oldRefreshToken['user_id'], $scopes); $refreshToken = $this->issueRefreshToken($accessToken); // Inject tokens into response $responseType->setAccessToken($accessToken); $responseType->setRefreshToken($refreshToken); return $responseType; }
/** * Respond to an access token request. * * @param \Psr\Http\Message\ServerRequestInterface $request * @param \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface $responseType * @param \DateInterval $accessTokenTTL * * @throws \League\OAuth2\Server\Exception\OAuthServerException * * @return \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface */ public function respondToAccessTokenRequest(ServerRequestInterface $request, ResponseTypeInterface $responseType, DateInterval $accessTokenTTL) { // Validate request $client = $this->validateClient($request); $encryptedAuthCode = $this->getRequestParameter('code', $request, null); if ($encryptedAuthCode === null) { throw OAuthServerException::invalidRequest('code'); } // Validate the authorization code try { $authCodePayload = json_decode($this->decrypt($encryptedAuthCode)); if (time() > $authCodePayload->expire_time) { throw OAuthServerException::invalidRequest('code', 'Authorization code has expired'); } if ($this->authCodeRepository->isAuthCodeRevoked($authCodePayload->auth_code_id) === true) { throw OAuthServerException::invalidRequest('code', 'Authorization code has been revoked'); } if ($authCodePayload->client_id !== $client->getIdentifier()) { throw OAuthServerException::invalidRequest('code', 'Authorization code was not issued to this client'); } // The redirect URI is required in this request $redirectUri = $this->getRequestParameter('redirect_uri', $request, null); if (empty($authCodePayload->redirect_uri) === false && $redirectUri === null) { throw OAuthServerException::invalidRequest('redirect_uri'); } if ($authCodePayload->redirect_uri !== $redirectUri) { throw OAuthServerException::invalidRequest('redirect_uri', 'Invalid redirect URI'); } $scopes = []; foreach ($authCodePayload->scopes as $scopeId) { $scope = $this->scopeRepository->getScopeEntityByIdentifier($scopeId); if (!$scope instanceof ScopeEntityInterface) { // @codeCoverageIgnoreStart throw OAuthServerException::invalidScope($scopeId); // @codeCoverageIgnoreEnd } $scopes[] = $scope; } // Finalize the requested scopes $scopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client, $authCodePayload->user_id); } catch (\LogicException $e) { throw OAuthServerException::invalidRequest('code', 'Cannot decrypt the authorization code'); } // Validate code challenge if ($this->enableCodeExchangeProof === true) { $codeVerifier = $this->getRequestParameter('code_verifier', $request, null); if ($codeVerifier === null) { throw OAuthServerException::invalidRequest('code_verifier'); } switch ($authCodePayload->code_challenge_method) { case 'plain': if (hash_equals($codeVerifier, $authCodePayload->code_challenge) === false) { throw OAuthServerException::invalidGrant('Failed to verify `code_verifier`.'); } break; case 'S256': if (hash_equals(urlencode(base64_encode(hash('sha256', $codeVerifier))), $authCodePayload->code_challenge) === false) { throw OAuthServerException::invalidGrant('Failed to verify `code_verifier`.'); } // @codeCoverageIgnoreStart break; default: throw OAuthServerException::serverError(sprintf('Unsupported code challenge method `%s`', $authCodePayload->code_challenge_method)); // @codeCoverageIgnoreEnd } } // Issue and persist access + refresh tokens $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $authCodePayload->user_id, $scopes); $refreshToken = $this->issueRefreshToken($accessToken); // Inject tokens into response type $responseType->setAccessToken($accessToken); $responseType->setRefreshToken($refreshToken); // Revoke used auth code $this->authCodeRepository->revokeAuthCode($authCodePayload->auth_code_id); return $responseType; }