diff --git a/README.md b/README.md index e9e9d11..83885cc 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,11 @@ if (!isset($_GET['code'])) { // Use these details to create a new profile printf('Hello %s!', $user->getName()); + // Or get more information with token Introspection + $user = $provider->getResourceOwnerFromIntrospectedToken($token); + // Use these details for user roles + echo '
'. var_export($user->toArray()["realm_access"]).'
'; + } catch (Exception $e) { exit('Failed to get resource owner: '.$e->getMessage()); } diff --git a/examples/index.php b/examples/index.php index 398333f..0cabcfa 100644 --- a/examples/index.php +++ b/examples/index.php @@ -43,6 +43,11 @@ $user = $provider->getResourceOwner($token); // Use these details to create a new profile printf('Hello %s!\n
', $user->getName()); + + // Or get more information with token Introspection + $user = $provider->getResourceOwnerFromIntrospectedToken($token); + // Use these details for user roles + echo '
'. var_export($user->toArray()["realm_access"]).'
'; } catch (Exception $e) { exit('Failed to get resource owner: '.$e->getMessage()); diff --git a/src/Provider/Keycloak.php b/src/Provider/Keycloak.php index 57cd922..e1f22de 100644 --- a/src/Provider/Keycloak.php +++ b/src/Provider/Keycloak.php @@ -4,6 +4,8 @@ use Exception; use Firebase\JWT\JWT; +use GuzzleHttp\Client; +use GuzzleHttp\RequestOptions; use League\OAuth2\Client\Provider\AbstractProvider; use League\OAuth2\Client\Provider\Exception\IdentityProviderException; use League\OAuth2\Client\Token\AccessToken; @@ -130,6 +132,18 @@ public function getResourceOwnerDetailsUrl(AccessToken $token) return $this->getBaseUrlWithRealm().'/protocol/openid-connect/userinfo'; } + /** + * Get provider url to fetch introspect token + * + * @param AccessToken $token + * + * @return string + */ + public function getIntrospectTokenUrl(AccessToken $token) + { + return $this->getBaseUrlWithRealm() . '/protocol/openid-connect/token/introspect'; + } + /** * Builds the logout URL. * @@ -154,6 +168,23 @@ private function getBaseLogoutUrl() return $this->getBaseUrlWithRealm() . '/protocol/openid-connect/logout'; } + private function fetchIntrospectToken(AccessToken $token) { + $data = array( + 'form_params' => array( + "token" => $token->getToken(), + "client_id" => $this->clientId, + "client_secret" => $this->clientSecret ), + RequestOptions::SYNCHRONOUS => true + ); + + $url = $this->getIntrospectTokenUrl($token); + + $client = new Client(); + $response = $client->requestAsync(self::METHOD_POST, $url, $data)->wait(); + $parsed = $this->parseResponse($response); + return $parsed; + } + /** * Creates base url from provider configuration. * @@ -220,6 +251,21 @@ public function getResourceOwner(AccessToken $token) return $this->createResourceOwner($response, $token); } + /** + * Requests and returns the resource owner of given access token introspection. + * + * @param AccessToken $token + * @return KeycloakResourceOwner + */ + public function getResourceOwnerFromIntrospectedToken(AccessToken $token) + { + $parsed = $this->fetchIntrospectToken($token); + + $response = $this->decryptResponse($parsed); + + return $this->createResourceOwner($response, $token); + } + /** * Updates expected encryption algorithm of Keycloak instance. *