/** * {@inheritdoc} */ public function checkRefreshToken(RefreshTokenInterface $token, ClientInterface $client) { if ($client->getPublicId() !== $token->getClientPublicId()) { throw $this->getExceptionManager()->getException(ExceptionManagerInterface::BAD_REQUEST, ExceptionManagerInterface::INVALID_GRANT, 'Invalid refresh token'); } if ($token->hasExpired()) { throw $this->getExceptionManager()->getException(ExceptionManagerInterface::BAD_REQUEST, ExceptionManagerInterface::INVALID_GRANT, 'Refresh token has expired'); } }
/** * {@inheritdoc} */ public function grantAccessToken(ServerRequestInterface $request, ClientInterface $client, GrantTypeResponseInterface &$grant_type_response) { if ($client->isPublic()) { throw $this->getExceptionManager()->getBadRequestException(ExceptionManagerInterface::ERROR_INVALID_CLIENT, 'The client is not a confidential client'); } $issue_refresh_token = $this->isRefreshTokenIssuedWithAccessToken(); $grant_type_response->setResourceOwnerPublicId($client->getPublicId()); $grant_type_response->setUserAccountPublicId(null); $grant_type_response->setRefreshTokenIssued($issue_refresh_token); $grant_type_response->setRefreshTokenScope($grant_type_response->getRequestedScope()); }
protected function addAuthCode($code, $expiresAt, ClientInterface $client, EndUserInterface $end_user, array $query_params, $redirectUri, array $scope = [], $issueRefreshToken = false) { $class = $this->getClass(); /* * @var \SpomkyLabs\OAuth2ServerBundle\Plugin\AuthCodeGrantTypePlugin\Model\AuthCodeInterface */ $authcode = new $class(); $authcode->setRedirectUri($redirectUri)->setQueryParams($query_params)->setIssueRefreshToken($issueRefreshToken)->setToken($code)->setResourceOwnerPublicId($end_user->getPublicId())->setExpiresAt($expiresAt)->setClientPublicId($client->getPublicId())->setScope($scope); $this->getEntityManager()->persist($authcode); $this->getEntityManager()->flush(); return $authcode; }
public function createUsedRefreshToken(ClientInterface $client, ResourceOwnerInterface $resource_owner, $refresh_token) { $class = $this->getClass(); $expired_date = (new \Datetime('now +1 year'))->format('U'); $token = new $class(); /* * @var $token \OAuth2\Token\RefreshTokenInterface */ $token->setToken($refresh_token)->setExpiresAt($expired_date)->setResourceOwnerPublicId($resource_owner->getPublicId())->setClientPublicId($client->getPublicId())->setUsed(true); $this->getEntityManager()->persist($token); $this->getEntityManager()->flush(); return $token; }
/** * {@inheritdoc} */ public function grantAccessToken(ServerRequestInterface $request, ClientInterface $client, GrantTypeResponseInterface &$grant_type_response) { if (!$client instanceof ConfidentialClientInterface) { throw $this->getExceptionManager()->getException(ExceptionManagerInterface::BAD_REQUEST, ExceptionManagerInterface::INVALID_CLIENT, 'The client is not a confidential client'); } $issue_refresh_token = $this->getConfiguration()->get('issue_refresh_token_with_client_credentials_grant_type', false); $scope = RequestBody::getParameter($request, 'scope'); $grant_type_response->setRequestedScope($scope); $grant_type_response->setAvailableScope(null); $grant_type_response->setResourceOwnerPublicId($client->getPublicId()); $grant_type_response->setRefreshTokenIssued($issue_refresh_token); $grant_type_response->setRefreshTokenScope($scope); $grant_type_response->setRefreshTokenRevoked(null); }
/** * {@inheritdoc} */ public function createAuthCode(ClientInterface $client, UserAccountInterface $resource_owner, array $query_params, $redirectUri, array $scope = [], $issueRefreshToken = false) { $auth_code = $this->createEmptyAuthorizationCode(); $auth_code->setScope($scope); $auth_code->setResourceOwnerPublicId($resource_owner->getUserPublicId()); $auth_code->setUserAccountPublicId($resource_owner->getPublicId()); $auth_code->setClientPublicId($client->getPublicId()); $auth_code->setExpiresAt(time() + $this->getLifetime($client)); $auth_code->setToken($this->generateAuthorizationCode()); $auth_code->setIssueRefreshToken($issueRefreshToken); $auth_code->setQueryParams($query_params); $auth_code->setMetadata('redirect_uri', $redirectUri); $this->updateAuthCode($auth_code); $this->saveAuthorizationCode($auth_code); return $auth_code; }
/** * {@inheritdoc} */ public function createRefreshToken(ClientInterface $client, ResourceOwnerInterface $resource_owner, array $scope = [], array $metadatas = []) { $refresh_token = $this->createEmptyRefreshToken(); $refresh_token->setScope($scope); if ($resource_owner instanceof UserAccountInterface) { $refresh_token->setResourceOwnerPublicId($resource_owner->getUserPublicId()); $refresh_token->setUserAccountPublicId($resource_owner->getPublicId()); } else { $refresh_token->setResourceOwnerPublicId($resource_owner->getPublicId()); } $refresh_token->setClientPublicId($client->getPublicId()); $refresh_token->setExpiresAt(time() + $this->getLifetime($client)); $refresh_token->setToken($this->generateToken()); $refresh_token->setMetadatas($metadatas); $this->updateRefreshToken($refresh_token); $this->saveRefreshToken($refresh_token); return $refresh_token; }
protected function addAccessToken($token, $expiresAt, ClientInterface $client, ResourceOwnerInterface $resourceOwner, array $scope = [], BaseRefreshTokenInterface $refresh_token = null) { if (null !== $this->event_dispatcher) { $this->event_dispatcher->dispatch(Events::OAUTH2_PRE_ACCESS_TOKEN_CREATION, new PreAccessTokenCreationEvent($client, $scope, $resourceOwner, $refresh_token)); } $class = $this->getClass(); /* * @var \SpomkyLabs\OAuth2ServerBundle\Plugin\SimpleStringAccessTokenPlugin\Model\SimpleStringAccessTokenInterface */ $access_token = new $class(); $access_token->setToken($token)->setExpiresAt($expiresAt)->setClientPublicId($client->getPublicId())->setScope($scope); if (null !== $resourceOwner) { $access_token->setResourceOwnerPublicId($resourceOwner->getPublicId()); } if (null !== $refresh_token) { $access_token->setRefreshToken($refresh_token->getToken()); } $this->getEntityManager()->persist($access_token); $this->getEntityManager()->flush(); if (null !== $this->event_dispatcher) { $this->event_dispatcher->dispatch(Events::OAUTH2_POST_ACCESS_TOKEN_CREATION, new PostAccessTokenCreationEvent($access_token)); } return $access_token; }
/** * @param \OAuth2\Token\AccessTokenInterface|\OAuth2\Token\RefreshTokenInterface $token * @param \OAuth2\Client\ClientInterface|null $client * * @return bool */ private function isClientVerified($token, ClientInterface $client = null) { if (null !== $client) { // The client ID of the token is the same as client authenticated return $token->getClientPublicId() === $client->getPublicId(); } else { // We try to get the client $client = $this->getClientManagerSupervisor()->getClient($token->getClientPublicId()); // Return false if the client is a confidential client (confidential client must be authenticated) return !$client instanceof ConfidentialClientInterface; } }
/** * @param \Psr\Http\Message\ServerRequestInterface $request * @param \Psr\Http\Message\ResponseInterface $response * @param \OAuth2\Client\ClientInterface $client */ private function handlePut(ServerRequestInterface $request, ResponseInterface &$response, ClientInterface $client) { $request_parameters = RequestBody::getParameters($request); $this->checkPreservedParameters($request_parameters); $this->checkSoftwareStatement($request_parameters); $client_data = $client->all(); foreach (['registration_access_token', 'registration_client_uri', 'client_secret_expires_at', 'client_id_issued_at'] as $k) { if (array_key_exists($k, $client_data)) { unset($client_data[$k]); } } $diff_data = array_diff_key($client_data, $request_parameters); Assertion::true(empty($diff_data), 'The request must include all client metadata fields.'); Assertion::eq($request_parameters['client_id'], $client->getPublicId(), 'Inconsistent "client_id" parameter.'); unset($request_parameters['client_id']); $request_parameters = array_merge($request_parameters, ['registration_access_token' => null, 'registration_client_uri' => null, 'client_secret_expires_at' => null]); foreach ($request_parameters as $k => $v) { if (empty($v)) { $client->remove($k); unset($request_parameters[$k]); } } $this->getClientRuleManager()->processParametersForClient($client, $request_parameters); $this->getClientManager()->saveClient($client); $this->processResponseWithClient($response, $client); }
/** * @param \OAuth2\Endpoint\TokenType\RevocationTokenTypeInterface $token_type * @param string $token * @param \OAuth2\Client\ClientInterface $client * * @return bool */ private function tryRevokeToken(RevocationTokenTypeInterface $token_type, $token, ClientInterface $client) { $result = $token_type->getToken($token); if ($result instanceof TokenInterface) { if ($result->getClientPublicId() === $client->getPublicId()) { $token_type->revokeToken($result); return true; } } return false; }
/** * {@inheritdoc} */ protected function getRegistrationClientUri(ClientInterface $client) { return $this->router->generate('oauth2_server_client_configuration', ['client_id' => $client->getPublicId()], UrlGeneratorInterface::ABSOLUTE_URL); }
/** * @param \OAuth2\Token\AuthCodeInterface $authCode * @param \OAuth2\Client\ClientInterface $client * * @throws \OAuth2\Exception\BaseExceptionInterface */ protected function checkAuthCode(AuthCodeInterface $authCode, ClientInterface $client) { if ($client->getPublicId() !== $authCode->getClientPublicId()) { throw $this->getExceptionManager()->getException(ExceptionManagerInterface::BAD_REQUEST, ExceptionManagerInterface::INVALID_GRANT, "Code doesn't exist or is invalid for the client."); } if ($authCode->hasExpired()) { throw $this->getExceptionManager()->getException(ExceptionManagerInterface::BAD_REQUEST, ExceptionManagerInterface::INVALID_GRANT, 'The authorization code has expired.'); } }
/** * @param \Psr\Http\Message\ResponseInterface $response * @param \OAuth2\Endpoint\TokenType\IntrospectionTokenTypeInterface $token_type * @param string $token * @param \OAuth2\Client\ClientInterface $client * * @return bool */ private function tryIntrospectToken(ResponseInterface &$response, IntrospectionTokenTypeInterface $token_type, $token, ClientInterface $client) { $result = $token_type->getToken($token); if ($result instanceof TokenInterface) { if ($result->getClientPublicId() === $client->getPublicId() || true === $this->isClientAResourceServer($client)) { $data = $token_type->introspectToken($result, $client); $this->populateResponse($response, $data); return true; } } return false; }
/** * {@inheritdoc} */ public function introspectToken(TokenInterface $token, ClientInterface $client) { if (!$token instanceof AccessTokenInterface) { return []; } $result = ['active' => !$token->hasExpired(), 'client_id' => $token->getClientPublicId(), 'token_type' => $token->getTokenTypeParameter('token_type'), 'exp' => $token->getExpiresAt()]; // If the client is the subject, we add this information. // // The subject is not added if the client is not a resource owner. // The reason is that if the client received an ID Token, the subject may have been computed (pairwise) and // the subject returned here may be different. As per the OpenID Connect specification, the client must reject the token // if subject are different and we want to avoid this case. if ($client->getPublicId() === $token->getResourceOwnerPublicId()) { $result['sub'] = $token->getResourceOwnerPublicId(); } // If the client is a resource server, we return all the information stored in the access token including the metadata if ($client->has('is_resource_server') && true === $client->get('is_resource_server')) { $result['sub'] = $token->getResourceOwnerPublicId(); } if (!empty($token->getScope())) { $result['scp'] = $token->getScope(); } if ($token instanceof JWTAccessTokenInterface) { $result = array_merge($result, $this->getJWTInformation($token->getJWS())); } return $result; }
/** * {@inheritdoc} */ public function grantAccessToken(ServerRequestInterface $request, ClientInterface $client, GrantTypeResponseInterface &$grant_type_response) { if (false === $client->hasPublicKeySet()) { throw $this->getExceptionManager()->getBadRequestException(ExceptionManagerInterface::ERROR_INVALID_CLIENT, 'The client is not a client with signature capabilities.'); } $jwt = $grant_type_response->getAdditionalData('jwt'); try { $this->getJWTLoader()->verify($jwt, $client->getPublicKeySet()); } catch (\Exception $e) { throw $this->getExceptionManager()->getBadRequestException(ExceptionManagerInterface::ERROR_INVALID_REQUEST, $e->getMessage()); } $issue_refresh_token = $this->isRefreshTokenIssuedWithAccessToken(); $grant_type_response->setResourceOwnerPublicId($client->getPublicId()); $grant_type_response->setUserAccountPublicId(null); $grant_type_response->setRefreshTokenIssued($issue_refresh_token); $grant_type_response->setRefreshTokenScope($grant_type_response->getRequestedScope()); }
/** * @param string $token * @param int $expiresAt * @param \OAuth2\Client\ClientInterface $client * @param array $scope * @param \OAuth2\ResourceOwner\ResourceOwnerInterface $resourceOwner * * @return mixed */ protected function addRefreshToken($token, $expiresAt, ClientInterface $client, ResourceOwnerInterface $resourceOwner, array $scope = []) { $class = $this->getClass(); /* * @var \OAuth2\Token\RefreshTokenInterface */ $refresh_token = new $class(); $refresh_token->setClientPublicId($client->getPublicId())->setExpiresAt($expiresAt)->setResourceOwnerPublicId($resourceOwner->getPublicId())->setToken($token)->setScope($scope); $this->save($refresh_token); return $refresh_token; }
/** * @param \OAuth2\Token\AccessTokenInterface $access_token * @param \OAuth2\Client\ClientInterface|null $resource_server * * @return array */ protected function preparePayload(AccessTokenInterface $access_token, ClientInterface $resource_server = null) { $aud = [$this->getIssuer()]; if (null !== $resource_server) { $access_token[] = $resource_server->getPublicId(); } $payload = ['jti' => Base64Url::encode(random_bytes(25)), 'iss' => $this->getIssuer(), 'aud' => $aud, 'iat' => time(), 'nbf' => time(), 'exp' => $access_token->getExpiresAt(), 'sub' => $access_token->getClientPublicId(), 'token_type' => $access_token->getTokenTypeParameter('token_type'), 'scp' => $access_token->getScope(), 'resource_owner' => $access_token->getResourceOwnerPublicId(), 'user_account' => $access_token->getUserAccountPublicId()]; $payload['metadatas'] = $access_token->getMetadatas(); if (0 !== ($expires_at = $access_token->getExpiresAt())) { $payload['exp'] = $expires_at; } if (!empty($access_token->getParameters())) { $parameters = $access_token->getParameters(); //This part should be updated to support 'cnf' (confirmation) claim (see POP). $payload['other'] = $parameters; } if (null !== $access_token->getRefreshToken()) { $payload['refresh_token'] = $access_token->getRefreshToken(); } return $payload; }