67 protected $storageMap = array(
68 'access_token' =>
'OAuth2\Storage\AccessTokenInterface',
69 'authorization_code' =>
'OAuth2\Storage\AuthorizationCodeInterface',
70 'client_credentials' =>
'OAuth2\Storage\ClientCredentialsInterface',
71 'client' =>
'OAuth2\Storage\ClientInterface',
72 'refresh_token' =>
'OAuth2\Storage\RefreshTokenInterface',
73 'user_credentials' =>
'OAuth2\Storage\UserCredentialsInterface',
74 'user_claims' =>
'OAuth2\OpenID\Storage\UserClaimsInterface',
75 'public_key' =>
'OAuth2\Storage\PublicKeyInterface',
76 'jwt_bearer' =>
'OAuth2\Storage\JWTBearerInterface',
77 'scope' =>
'OAuth2\Storage\ScopeInterface',
80 protected $responseTypeMap = array(
81 'token' =>
'OAuth2\ResponseType\AccessTokenInterface',
82 'code' =>
'OAuth2\ResponseType\AuthorizationCodeInterface',
83 'id_token' =>
'OAuth2\OpenID\ResponseType\IdTokenInterface',
84 'id_token token' =>
'OAuth2\OpenID\ResponseType\IdTokenTokenInterface',
85 'code id_token' =>
'OAuth2\OpenID\ResponseType\CodeIdTokenInterface',
103 $storage = is_array($storage) ? $storage : array($storage);
104 $this->storages = array();
105 foreach ($storage
as $key => $service) {
106 $this->addStorage($service, $key);
110 $this->config = array_merge(array(
111 'use_jwt_access_tokens' =>
false,
112 'store_encrypted_token_string' =>
true,
113 'use_openid_connect' =>
false,
114 'id_lifetime' => 3600,
115 'access_lifetime' => 3600,
116 'www_realm' =>
'Service',
117 'token_param_name' =>
'access_token',
118 'token_bearer_header_name' =>
'Bearer',
119 'enforce_state' =>
true,
120 'require_exact_redirect_uri' =>
true,
121 'allow_implicit' =>
false,
122 'allow_credentials_in_request_body' =>
true,
123 'allow_public_clients' =>
true,
124 'always_issue_new_refresh_token' =>
false,
125 'unset_refresh_token_after_use' =>
true,
128 foreach ($grantTypes
as $key => $grantType) {
129 $this->addGrantType($grantType, $key);
132 foreach ($responseTypes
as $key => $responseType) {
133 $this->addResponseType($responseType, $key);
136 $this->tokenType = $tokenType;
137 $this->scopeUtil = $scopeUtil;
138 $this->clientAssertionType = $clientAssertionType;
140 if ($this->config[
'use_openid_connect']) {
141 $this->validateOpenIdConnect();
147 if (is_null($this->authorizeController)) {
148 $this->authorizeController = $this->createDefaultAuthorizeController();
151 return $this->authorizeController;
156 if (is_null($this->tokenController)) {
157 $this->tokenController = $this->createDefaultTokenController();
160 return $this->tokenController;
165 if (is_null($this->resourceController)) {
166 $this->resourceController = $this->createDefaultResourceController();
169 return $this->resourceController;
174 if (is_null($this->userInfoController)) {
175 $this->userInfoController = $this->createDefaultUserInfoController();
178 return $this->userInfoController;
186 $this->authorizeController = $authorizeController;
194 $this->tokenController = $tokenController;
202 $this->resourceController = $resourceController;
210 $this->userInfoController = $userInfoController;
230 $this->response = is_null($response) ?
new Response() : $response;
231 $this->getUserInfoController()->handleUserInfoRequest($request, $this->response);
233 return $this->response;
258 $this->response = is_null($response) ?
new Response() : $response;
259 $this->getTokenController()->handleTokenRequest($request, $this->response);
261 return $this->response;
266 $this->response = is_null($response) ?
new Response() : $response;
267 $value = $this->getTokenController()->grantAccessToken($request, $this->response);
284 $this->response = is_null($response) ?
new Response() : $response;
285 $this->getTokenController()->handleRevokeRequest($request, $this->response);
287 return $this->response;
320 $this->response = $response;
321 $this->getAuthorizeController()->handleAuthorizeRequest($request, $this->response, $is_authorized, $user_id);
323 return $this->response;
347 $this->response = is_null($response) ?
new Response() : $response;
348 $value = $this->getAuthorizeController()->validateAuthorizeRequest($request, $this->response);
355 $this->response = is_null($response) ?
new Response() : $response;
356 $value = $this->getResourceController()->verifyResourceRequest($request, $this->response, $scope);
363 $this->response = is_null($response) ?
new Response() : $response;
364 $value = $this->getResourceController()->getAccessTokenData($request, $this->response);
371 if (!is_string($identifier)) {
375 $this->grantTypes[$identifier] = $grantType;
378 if (!is_null($this->tokenController)) {
379 $this->getTokenController()->addGrantType($grantType, $identifier);
396 if (isset($this->storageMap[$key])) {
397 if (!is_null($storage) && !$storage instanceof $this->storageMap[$key]) {
398 throw new \InvalidArgumentException(sprintf(
'storage of type "%s" must implement interface "%s"', $key, $this->storageMap[$key]));
400 $this->storages[$key] = $storage;
403 if ($key ===
'client' && !isset($this->storages[
'client_credentials'])) {
404 if ($storage instanceof \
OAuth2\Storage\ClientCredentialsInterface) {
405 $this->storages[
'client_credentials'] = $storage;
407 } elseif ($key ===
'client_credentials' && !isset($this->storages[
'client'])) {
408 if ($storage instanceof \
OAuth2\Storage\ClientInterface) {
409 $this->storages[
'client'] = $storage;
412 } elseif (!is_null($key) && !is_numeric($key)) {
413 throw new \InvalidArgumentException(sprintf(
'unknown storage key "%s", must be one of [%s]', $key, implode(
', ', array_keys($this->storageMap))));
416 foreach ($this->storageMap
as $type => $interface) {
417 if ($storage instanceof $interface) {
418 $this->storages[$type] = $storage;
424 throw new \InvalidArgumentException(sprintf(
'storage of class "%s" must implement one of [%s]', get_class($storage), implode(
', ', $this->storageMap)));
431 $key = $this->normalizeResponseType($key);
433 if (isset($this->responseTypeMap[$key])) {
434 if (!$responseType instanceof $this->responseTypeMap[$key]) {
435 throw new \InvalidArgumentException(sprintf(
'responseType of type "%s" must implement interface "%s"', $key, $this->responseTypeMap[$key]));
437 $this->responseTypes[$key] = $responseType;
438 } elseif (!is_null($key) && !is_numeric($key)) {
439 throw new \InvalidArgumentException(sprintf(
'unknown responseType key "%s", must be one of [%s]', $key, implode(
', ', array_keys($this->responseTypeMap))));
442 foreach ($this->responseTypeMap
as $type => $interface) {
443 if ($responseType instanceof $interface) {
444 $this->responseTypes[$type] = $responseType;
450 throw new \InvalidArgumentException(sprintf(
'Unknown response type %s. Please implement one of [%s]', get_class($responseType), implode(
', ', $this->responseTypeMap)));
457 if (!$this->scopeUtil) {
458 $storage = isset($this->storages[
'scope']) ? $this->storages[
'scope'] :
null;
459 $this->scopeUtil =
new Scope($storage);
462 return $this->scopeUtil;
470 $this->scopeUtil = $scopeUtil;
475 if (!isset($this->storages[
'client'])) {
476 throw new \LogicException(
"You must supply a storage object implementing OAuth2\Storage\ClientInterface to use the authorize server");
478 if (0 == count($this->responseTypes)) {
479 $this->responseTypes = $this->getDefaultResponseTypes();
481 if ($this->config[
'use_openid_connect'] && !isset($this->responseTypes[
'id_token'])) {
482 $this->responseTypes[
'id_token'] = $this->createDefaultIdTokenResponseType();
483 if ($this->config[
'allow_implicit']) {
484 $this->responseTypes[
'id_token token'] = $this->createDefaultIdTokenTokenResponseType();
488 $config = array_intersect_key($this->config, array_flip(explode(
' ',
'allow_implicit enforce_state require_exact_redirect_uri')));
490 if ($this->config[
'use_openid_connect']) {
491 return new OpenIDAuthorizeController($this->storages[
'client'], $this->responseTypes,
$config, $this->getScopeUtil());
499 if (0 == count($this->grantTypes)) {
500 $this->grantTypes = $this->getDefaultGrantTypes();
503 if (is_null($this->clientAssertionType)) {
505 foreach ($this->grantTypes
as $grantType) {
507 if (!isset($this->storages[
'client_credentials'])) {
508 throw new \LogicException(
"You must supply a storage object implementing OAuth2\Storage\ClientCredentialsInterface to use the token server");
510 $config = array_intersect_key($this->config, array_flip(explode(
' ',
'allow_credentials_in_request_body allow_public_clients')));
511 $this->clientAssertionType =
new HttpBasic($this->storages[
'client_credentials'],
$config);
517 if (!isset($this->storages[
'client'])) {
518 throw new \LogicException(
"You must supply a storage object implementing OAuth2\Storage\ClientInterface to use the token server");
521 $accessTokenResponseType = $this->getAccessTokenResponseType();
523 return new TokenController($accessTokenResponseType, $this->storages[
'client'], $this->grantTypes, $this->clientAssertionType, $this->getScopeUtil());
528 if ($this->config[
'use_jwt_access_tokens']) {
530 if (!isset($this->storages[
'access_token']) || !$this->storages[
'access_token'] instanceof
JwtAccessTokenInterface) {
531 $this->storages[
'access_token'] = $this->createDefaultJwtAccessTokenStorage();
533 } elseif (!isset($this->storages[
'access_token'])) {
534 throw new \LogicException(
"You must supply a storage object implementing OAuth2\Storage\AccessTokenInterface or use JwtAccessTokens to use the resource server");
537 if (!$this->tokenType) {
538 $this->tokenType = $this->getDefaultTokenType();
541 $config = array_intersect_key($this->config, array(
'www_realm' =>
''));
548 if ($this->config[
'use_jwt_access_tokens']) {
550 if (!isset($this->storages[
'access_token']) || !$this->storages[
'access_token'] instanceof
JwtAccessTokenInterface) {
551 $this->storages[
'access_token'] = $this->createDefaultJwtAccessTokenStorage();
553 } elseif (!isset($this->storages[
'access_token'])) {
554 throw new \LogicException(
"You must supply a storage object implementing OAuth2\Storage\AccessTokenInterface or use JwtAccessTokens to use the UserInfo server");
557 if (!isset($this->storages[
'user_claims'])) {
558 throw new \LogicException(
"You must supply a storage object implementing OAuth2\OpenID\Storage\UserClaimsInterface to use the UserInfo server");
561 if (!$this->tokenType) {
562 $this->tokenType = $this->getDefaultTokenType();
565 $config = array_intersect_key($this->config, array(
'www_realm' =>
''));
567 return new UserInfoController($this->tokenType, $this->storages[
'access_token'], $this->storages[
'user_claims'],
$config, $this->getScopeUtil());
572 $config = array_intersect_key($this->config, array_flip(explode(
' ',
'token_param_name token_bearer_header_name')));
579 $responseTypes = array();
581 if ($this->config[
'allow_implicit']) {
582 $responseTypes[
'token'] = $this->getAccessTokenResponseType();
585 if ($this->config[
'use_openid_connect']) {
586 $responseTypes[
'id_token'] = $this->getIdTokenResponseType();
587 if ($this->config[
'allow_implicit']) {
588 $responseTypes[
'id_token token'] = $this->getIdTokenTokenResponseType();
592 if (isset($this->storages[
'authorization_code'])) {
593 $config = array_intersect_key($this->config, array_flip(explode(
' ',
'enforce_redirect auth_code_lifetime')));
594 if ($this->config[
'use_openid_connect']) {
595 if (!$this->storages[
'authorization_code'] instanceof OpenIDAuthorizationCodeInterface) {
596 throw new \LogicException(
"Your authorization_code storage must implement OAuth2\OpenID\Storage\AuthorizationCodeInterface to work when 'use_openid_connect' is true");
598 $responseTypes[
'code'] =
new OpenIDAuthorizationCodeResponseType($this->storages[
'authorization_code'],
$config);
599 $responseTypes[
'code id_token'] =
new CodeIdToken($responseTypes[
'code'], $responseTypes[
'id_token']);
601 $responseTypes[
'code'] =
new AuthorizationCodeResponseType($this->storages[
'authorization_code'],
$config);
605 if (count($responseTypes) == 0) {
606 throw new \LogicException(
"You must supply an array of response_types in the constructor or implement a OAuth2\Storage\AuthorizationCodeInterface storage object or set 'allow_implicit' to true and implement a OAuth2\Storage\AccessTokenInterface storage object");
609 return $responseTypes;
614 $grantTypes = array();
616 if (isset($this->storages[
'user_credentials'])) {
617 $grantTypes[
'password'] =
new UserCredentials($this->storages[
'user_credentials']);
620 if (isset($this->storages[
'client_credentials'])) {
621 $config = array_intersect_key($this->config, array(
'allow_credentials_in_request_body' =>
''));
625 if (isset($this->storages[
'refresh_token'])) {
626 $config = array_intersect_key($this->config, array_flip(explode(
' ',
'always_issue_new_refresh_token unset_refresh_token_after_use')));
627 $grantTypes[
'refresh_token'] =
new RefreshToken($this->storages[
'refresh_token'],
$config);
630 if (isset($this->storages[
'authorization_code'])) {
631 if ($this->config[
'use_openid_connect']) {
632 if (!$this->storages[
'authorization_code'] instanceof OpenIDAuthorizationCodeInterface) {
633 throw new \LogicException(
"Your authorization_code storage must implement OAuth2\OpenID\Storage\AuthorizationCodeInterface to work when 'use_openid_connect' is true");
635 $grantTypes[
'authorization_code'] =
new OpenIDAuthorizationCodeGrantType($this->storages[
'authorization_code']);
637 $grantTypes[
'authorization_code'] =
new AuthorizationCode($this->storages[
'authorization_code']);
641 if (count($grantTypes) == 0) {
642 throw new \LogicException(
"Unable to build default grant types - You must supply an array of grant_types in the constructor");
650 if (isset($this->responseTypes[
'token'])) {
651 return $this->responseTypes[
'token'];
654 if ($this->config[
'use_jwt_access_tokens']) {
655 return $this->createDefaultJwtAccessTokenResponseType();
658 return $this->createDefaultAccessTokenResponseType();
663 if (isset($this->responseTypes[
'id_token'])) {
664 return $this->responseTypes[
'id_token'];
667 return $this->createDefaultIdTokenResponseType();
672 if (isset($this->responseTypes[
'id_token token'])) {
673 return $this->responseTypes[
'id_token token'];
676 return $this->createDefaultIdTokenTokenResponseType();
684 if (!isset($this->storages[
'public_key'])) {
685 throw new \LogicException(
"You must supply a storage object implementing OAuth2\Storage\PublicKeyInterface to use crypto tokens");
687 $tokenStorage =
null;
688 if (!
empty($this->config[
'store_encrypted_token_string']) && isset($this->storages[
'access_token'])) {
689 $tokenStorage = $this->storages[
'access_token'];
692 return new JwtAccessTokenStorage($this->storages[
'public_key'], $tokenStorage);
700 if (!isset($this->storages[
'public_key'])) {
701 throw new \LogicException(
"You must supply a storage object implementing OAuth2\Storage\PublicKeyInterface to use crypto tokens");
704 $tokenStorage =
null;
705 if (isset($this->storages[
'access_token'])) {
706 $tokenStorage = $this->storages[
'access_token'];
709 $refreshStorage =
null;
710 if (isset($this->storages[
'refresh_token'])) {
711 $refreshStorage = $this->storages[
'refresh_token'];
714 $config = array_intersect_key($this->config, array_flip(explode(
' ',
'store_encrypted_token_string issuer access_lifetime refresh_token_lifetime')));
721 if (!isset($this->storages[
'access_token'])) {
722 throw new \LogicException(
"You must supply a response type implementing OAuth2\ResponseType\AccessTokenInterface, or a storage object implementing OAuth2\Storage\AccessTokenInterface to use the token server");
725 $refreshStorage =
null;
726 if (isset($this->storages[
'refresh_token'])) {
727 $refreshStorage = $this->storages[
'refresh_token'];
730 $config = array_intersect_key($this->config, array_flip(explode(
' ',
'access_lifetime refresh_token_lifetime')));
731 $config[
'token_type'] = $this->tokenType ? $this->tokenType->getTokenType() : $this->getDefaultTokenType()->getTokenType();
738 if (!isset($this->storages[
'user_claims'])) {
739 throw new \LogicException(
"You must supply a storage object implementing OAuth2\OpenID\Storage\UserClaimsInterface to use openid connect");
741 if (!isset($this->storages[
'public_key'])) {
742 throw new \LogicException(
"You must supply a storage object implementing OAuth2\Storage\PublicKeyInterface to use openid connect");
745 $config = array_intersect_key($this->config, array_flip(explode(
' ',
'issuer id_lifetime')));
747 return new IdToken($this->storages[
'user_claims'], $this->storages[
'public_key'],
$config);
752 return new IdTokenToken($this->getAccessTokenResponseType(), $this->getIdTokenResponseType());
757 $authCodeGrant = $this->getGrantType(
'authorization_code');
758 if (!
empty($authCodeGrant) && !$authCodeGrant instanceof OpenIDAuthorizationCodeGrantType) {
759 throw new \InvalidArgumentException(
'You have enabled OpenID Connect, but supplied a grant type that does not support it.');
766 if (!
empty($name) &&
false !== strpos($name,
' ')) {
767 $types = explode(
' ', $name);
769 $name = implode(
' ', $types);
777 return $this->response;
782 return $this->storages;
787 return isset($this->storages[$name]) ? $this->storages[$name] :
null;
792 return $this->grantTypes;
797 return isset($this->grantTypes[$name]) ? $this->grantTypes[$name] :
null;
802 return $this->responseTypes;
808 $name = $this->normalizeResponseType($name);
810 return isset($this->responseTypes[$name]) ? $this->responseTypes[$name] :
null;
815 return $this->tokenType;
820 return $this->clientAssertionType;
825 $this->config[$name] = $value;
830 return isset($this->config[$name]) ? $this->config[$name] : $default;