/** * Register the service provider. * * @return void */ public function register() { $this->app->singleton('Atrauzzi\\Oauth2Server\\Config', function (Application $app) { $config = new Oauth2Config(); $config->setTokenStrategy($this->makeServerObject('TokenStrategy', config('token_strategy', 'bearer')))->setAuthorizationCodeTtl(config('oauth2.authorization_code_ttl', '300'))->setAccessTokenTtl(config('oauth2.access_token_ttl', 3600))->setRefreshTokenTtl(config('oauth2.refresh_token_ttl', 604800))->requireScopeParam(config('oauth2.require_scopes', false))->requireStateParam(config('oauth2.require_state', false))->rotateRefreshTokens(config('oauth2.rotate_refresh_tokens', false))->setDefaultScopes(config('oauth2.default_scopes')); return $config; }); // $this->app->singleton('Atrauzzi\LaravelOauth2Server\Config', function (Application $app) { // // $config = new LaravelOauth2Config(); // // return $config; // // }); $this->app->singleton('Atrauzzi\\Oauth2Server\\AuthorizationService', function (Application $app) { $grantTypes = []; foreach (config('oauth2.grant_types', ['authorization_code']) as $grantType) { $grantTypes[] = $this->makeServerObject('GrantType', $grantType); } return new AuthorizationService($app->make('Atrauzzi\\Oauth2Server\\Config'), $grantTypes); }); $this->app->singleton('Atrauzzi\\Oauth2Server\\Domain\\Repository\\AuthorizationCode', 'Atrauzzi\\LaravelOauth2Server\\Domain\\Repository\\Cache\\AuthorizationCode'); $this->app->singleton('Atrauzzi\\Oauth2Server\\Domain\\Repository\\AccessToken', 'Atrauzzi\\LaravelOauth2Server\\Domain\\Repository\\Cache\\AccessToken'); $this->app->singleton('Atrauzzi\\Oauth2Server\\Domain\\Repository\\RefreshToken', 'Atrauzzi\\LaravelOauth2Server\\Domain\\Repository\\Cache\\RefreshToken'); $this->app->singleton('Atrauzzi\\Oauth2Server\\Domain\\Repository\\Scope', 'Atrauzzi\\LaravelOauth2Server\\Domain\\Repository\\Eloquent\\Scope'); $this->app->singleton('Atrauzzi\\Oauth2Server\\Domain\\Repository\\Client', 'Atrauzzi\\LaravelOauth2Server\\Domain\\Repository\\Eloquent\\Client'); }
/** * @param \Symfony\Component\HttpFoundation\Request $request * @param bool $headerOnly * @throws \Atrauzzi\Oauth2Server\Exception\AccessDenied * @throws \Atrauzzi\Oauth2Server\Exception\InvalidRequest */ public function authorize(Request $request, $headerOnly = true) { if ($authorizationHeader = $request->headers->get('Authorization')) { $accessTokenId = $this->config->getTokenStrategy()->determineAccessTokenInHeader($request); } elseif (!$headerOnly) { $accessTokenId = $request->get($this->config->getTokenKey()); } else { throw new InvalidRequest('access_token'); } $accessToken = $this->accessTokenRepository->find($accessTokenId); if (empty($accessToken)) { throw new AccessDenied(); } if ($accessToken->isExpired()) { throw new AccessDenied(); } }
/** * Given a string list of scopes, return an array of valid Scope entities keyed by name. * * @param string $scopes * @param string $redirectUri * @param null|string $clientId * @param null|string $grantTypeIdentifier * @return null|\Atrauzzi\Oauth2Server\Domain\Entity\Scope[] * @throws \Atrauzzi\Oauth2Server\Exception\InvalidRequest * @throws \Atrauzzi\Oauth2Server\Exception\InvalidScope */ public function findValid($scopes, $grantTypeIdentifier = null, $clientId = null, $redirectUri = null) { if (!$scopes && !$this->config->scopeParamRequired()) { return null; } $requestedScopes = []; foreach (explode($this->config->getScopeDelimiter(), $scopes) as $scope) { if ($scope = trim($scope)) { $requestedScopes[] = $scope; } } $requestedScopes = empty($requestedScopes) ? $this->config->getDefaultScopes() : $requestedScopes; if ($this->config->scopeParamRequired() && empty($requestedScopes)) { throw new InvalidRequest('scope'); } $validScopes = $this->scopeRepository->findByNames($requestedScopes, $clientId, $grantTypeIdentifier); $invalidScopes = array_diff($requestedScopes ?: [], array_keys($validScopes)); if (!empty($invalidScopes)) { throw new InvalidScope($invalidScopes, $redirectUri); } return $validScopes; }
/** * Conducts the checks and operations necessary for the flow indicated in the request. * * @param \Symfony\Component\HttpFoundation\Request $request * @param int $grantTypeFlow * @param \Atrauzzi\Oauth2Server\Domain\Entity\Oauthable $oauthable * @return array * @throws \Atrauzzi\Oauth2Server\Exception\InvalidClient * @throws \Atrauzzi\Oauth2Server\Exception\InvalidRequest */ public function doFlow(Request $request, $grantTypeFlow, Oauthable $oauthable = null) { if (!($clientId = $request->get('client_id', $request->getUser()))) { throw new InvalidRequest('client_id'); } if (!($clientSecret = $request->get('client_secret', $request->getPassword()))) { throw new InvalidRequest('client_secret'); } if (!($client = $this->clientRepository->find($clientId, $clientSecret, $this->getIdentifier()))) { throw new InvalidClient(); } $scopes = $this->scopeService->findValid($request->get('scope')); // // $accessToken = $this->accessTokenRepository->create(SecureKey::generate(), $this->config->getAccessTokenTtl() + time(), $oauthable->getId(), $oauthable->getType(), $client->getId(), array_keys($scopes)); // ToDo: Do we do refresh tokens for this grant type? $this->accessTokenRepository->persist($accessToken); $tokenStrategy = $this->config->getTokenStrategy(); $tokenStrategy->setParam('access_token', $accessToken->getId()); $tokenStrategy->setParam('expires_in', $this->config->getAccessTokenTtl()); return $tokenStrategy->generateResponse(); }
/** * @param \Symfony\Component\HttpFoundation\Request $request * @param int $grantTypeFlow * @param \Atrauzzi\Oauth2Server\Domain\Entity\Oauthable $oauthable * @return array * @throws \Atrauzzi\Oauth2Server\Exception\InvalidClient * @throws \Atrauzzi\Oauth2Server\Exception\InvalidCredentials * @throws \Atrauzzi\Oauth2Server\Exception\InvalidRefresh * @throws \Atrauzzi\Oauth2Server\Exception\InvalidRequest * @throws \Atrauzzi\Oauth2Server\Exception\InvalidScope * @throws \Atrauzzi\Oauth2Server\Exception\UnsupportedFlow */ public function doFlow(Request $request, $grantTypeFlow, Oauthable $oauthable = null) { if ($grantTypeFlow != self::FLOW_DEFAULT) { throw new UnsupportedFlow(get_class(), $grantTypeFlow); } if (!($clientId = $request->get('client_id', $request->getUser()))) { throw new InvalidRequest('client_id'); } if (!($clientSecret = $request->get('client_secret', $request->getPassword()))) { throw new InvalidRequest('client_secret'); } if (!($oldRefreshTokenParam = $request->get('refresh_token', null))) { throw new InvalidRequest('refresh_token'); } if (!($client = $this->clientRepository->find($clientId, $clientSecret, $this->getIdentifier()))) { throw new InvalidClient(); } if (!($originalRefreshToken = $this->refreshTokenRepository->find($oldRefreshTokenParam))) { throw new InvalidRefresh(); } if ($originalRefreshToken->isExpired()) { throw new InvalidRefresh(); } // // $originalScopes = $originalRefreshToken->getScopeNames(); $requestedScopes = array_keys($this->scopeService->findValid($request->get('scope'), null, $client->getId(), $this->getIdentifier())); $disallowedScopes = array_diff($requestedScopes, $originalScopes); if (count($disallowedScopes)) { throw new InvalidScope($disallowedScopes); } $scopes = count($requestedScopes) ? $requestedScopes : $originalScopes; $accessToken = $this->accessTokenRepository->create(SecureKey::generate(), $this->config->getAccessTokenTtl() + time(), $originalRefreshToken->getOauthableId(), $originalRefreshToken->getOauthableType(), $client->getId(), $scopes); $tokenStrategy = $this->config->getTokenStrategy(); if ($this->config->shouldRotateRefreshTokens()) { $newRefreshToken = $this->refreshTokenRepository->create(SecureKey::generate(), $this->config->getRefreshTokenTtl() + time(), $originalRefreshToken->getOauthableId(), $originalRefreshToken->getOauthableType(), $client->getId(), $scopes); $this->refreshTokenRepository->delete($originalRefreshToken); unset($originalRefreshToken); $this->refreshTokenRepository->persist($newRefreshToken); $accessToken->setRefreshTokenId($newRefreshToken->getId()); // ToDo: Should we try to convey refresh token expiry? $tokenStrategy->setParam('refresh_token', $newRefreshToken->getId()); } $this->accessTokenRepository->persist($accessToken); $tokenStrategy->setParam('access_token', $accessToken->getId()); $tokenStrategy->setParam('expires_in', $this->config->getAccessTokenTtl()); return $tokenStrategy->generateResponse(); }
/** * Exchange an oauth code for an access and optionally a refresh token. * * @param \Symfony\Component\HttpFoundation\Request $request * @return array * @throws \Atrauzzi\Oauth2Server\Exception\InvalidClient * @throws \Atrauzzi\Oauth2Server\Exception\InvalidRequest */ protected function doExchangeFlow(Request $request) { if (!($clientId = $request->get('client_id', $request->getUser()))) { throw new InvalidRequest('client_id'); } if (!($clientSecret = $request->get('client_secret', $request->getPassword()))) { throw new InvalidRequest('client_secret'); } if (!($redirectUri = $request->request->get('redirect_uri', null))) { throw new InvalidRequest('redirect_uri'); } $client = $this->clientRepository->find($clientId, $clientSecret, $this->getIdentifier(), $redirectUri); if (!$client instanceof Client) { throw new InvalidClient(); } $authCode = $this->authorizationCodeRepository->find($request->get('code')); if (!$authCode instanceof AuthorizationCodeEntity) { throw new InvalidRequest('code'); } if ($authCode->isExpired()) { throw new InvalidRequest('code'); } if ($authCode->getRedirectUri() != $redirectUri) { throw new InvalidRequest('redirect_uri'); } // // $ttl = $this->config->getAccessTokenTtl(); $accessToken = $this->accessTokenRepository->create(SecureKey::generate(), $ttl + time(), $authCode->getOauthableId(), $authCode->getOauthableType(), $authCode->getClientId(), $authCode->getScopeNames()); $this->authorizationCodeRepository->delete($authCode); unset($authCode); $tokenStrategy = $this->config->getTokenStrategy(); if ($this->config->hasGrantType('refresh_token')) { $refreshToken = $this->refreshTokenRepository->create(SecureKey::generate(), $this->config->getRefreshTokenTtl() + time(), $accessToken->getOauthableId(), $accessToken->getOauthableType(), $accessToken->getClientId(), $accessToken->getScopeNames()); $this->refreshTokenRepository->persist($refreshToken); $accessToken->setRefreshTokenId($refreshToken->getId()); $tokenStrategy->setParam('refresh_token', $refreshToken->getId()); } $this->accessTokenRepository->persist($accessToken); $tokenStrategy->setParam('access_token', $accessToken->getId()); $tokenStrategy->setParam('expires_in', $ttl); return $tokenStrategy->generateResponse(); }
/** * @param \Symfony\Component\HttpFoundation\Request $request * @param int $grantTypeFlow * @param \Atrauzzi\Oauth2Server\Domain\Entity\Oauthable $oauthable * @return mixed * @throws \Atrauzzi\Oauth2Server\Exception\InvalidClient * @throws \Atrauzzi\Oauth2Server\Exception\InvalidCredentials * @throws \Atrauzzi\Oauth2Server\Exception\InvalidRequest * @throws \Atrauzzi\Oauth2Server\Exception\InvalidScope * @throws \Atrauzzi\Oauth2Server\Exception\ServerError */ public function doFlow(Request $request, $grantTypeFlow, Oauthable $oauthable = null) { if (!$oauthable instanceof Oauthable) { throw new InvalidCredentials(); } if ($clientId = $request->get('client_id', $request->getUser())) { throw new InvalidRequest('client_id'); } if ($clientSecret = $request->get('client_secret', $request->getPassword())) { throw new InvalidRequest('client_secret'); } if (!($client = $this->clientRepository->find($clientId, $clientSecret, $this->getIdentifier()))) { throw new InvalidClient(); } if (!($username = $request->get('username'))) { throw new InvalidRequest('username'); } if ($password = $request->get('password')) { throw new InvalidRequest('password'); } // // $scopes = $this->scopeService->findValid($request->get('scopes'), $this->getIdentifier(), $client->getId()); $accessToken = $this->accessTokenRepository->create(SecureKey::generate(), $this->config->getAccessTokenTtl() + time(), $oauthable->getId(), $oauthable->getType(), $client->getId(), array_keys($scopes)); $tokenStrategy = $this->config->getTokenStrategy(); if ($this->config->hasGrantType('refresh_token')) { $refreshToken = $this->refreshTokenRepository->create(SecureKey::generate(), $this->config->getRefreshTokenTtl() + time(), $oauthable->getId(), $oauthable->getType(), $client->getId(), array_keys($scopes)); $this->refreshTokenRepository->persist($refreshToken); $accessToken->setRefreshTokenId($refreshToken->getId()); $tokenStrategy->setParam('refresh_token', $refreshToken->getId()); } $this->accessTokenRepository->persist($accessToken); $tokenStrategy->setParam('access_token', $accessToken->getId()); $tokenStrategy->setParam('expires_in', $this->config->getAccessTokenTtl()); return $tokenStrategy->generateResponse(); }