diff --git a/OpenIDConnectClient.php5 b/OpenIDConnectClient.php5 index 80e1370c..60a3b00d 100644 --- a/OpenIDConnectClient.php5 +++ b/OpenIDConnectClient.php5 @@ -89,6 +89,11 @@ class OpenIDConnectClient */ private $accessToken; + /** + * @var string needed for logout + */ + private $id_token; + /** * @var array holds scopes */ @@ -99,6 +104,13 @@ class OpenIDConnectClient */ private $userInfo = array(); + /** + * the logout url + */ + public function getLogOutURL() { + return $this->getProviderConfigValue('end_session_endpoint'); + } + /** * @param $provider_url string optional * @@ -119,6 +131,14 @@ class OpenIDConnectClient $this->providerConfig['issuer'] = $provider_url; } + public function getAccessToken() { + return $this->accessToken; + } + + public function getIdToken() { + return $this->id_token; + } + /** * @return bool * @throws OpenIDConnectClientException @@ -157,6 +177,9 @@ class OpenIDConnectClient // Save the access token $this->accessToken = $token_json->access_token; + // Save the id_token, needed for logout + $this->id_token = $token_json->id_token; + // Success! return true; @@ -190,8 +213,8 @@ class OpenIDConnectClient // If the configuration value is not available, attempt to fetch it from a well known config endpoint // This is also known as auto "discovery" if (!isset($this->providerConfig[$param])) { - $well_known_config_url = rtrim(self::getProviderURL(),"/") . "/.well-known/openid-configuration"; - $value = json_decode(self::fetchURL($well_known_config_url))->{$param}; + $well_known_config_url = rtrim(self::getProviderURL(),'/') . "/.well-known/openid-configuration"; + $value = json_decode(self::fetchURL($well_known_config_url))->{$param}; if ($value) { $this->providerConfig[$param] = $value; @@ -280,27 +303,49 @@ class OpenIDConnectClient * @param $code * @return mixed */ - private function requestTokens($code) { + private function requestTokens($code) { + $token_endpoint = self::getProviderConfigValue("token_endpoint"); + $ch = curl_init($token_endpoint); - $token_endpoint = self::getProviderConfigValue("token_endpoint"); + $grant_type = "authorization_code"; + $token_params = array( + 'grant_type' => $grant_type, + 'code' => $code, + 'redirect_uri' => self::getRedirectURL() + ); - $grant_type = "authorization_code"; - $token_params = array( - 'grant_type' => $grant_type, - 'code' => $code, - 'redirect_uri' => self::getRedirectURL(), - 'client_id' => $this->clientID, - 'client_secret' => $this->clientSecret - ); + // Convert token params to string format + $token_params = http_build_query($token_params, null, '&'); - // Convert token params to string format - $token_params = http_build_query($token_params, null, '&'); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $token_params); + $content_type = 'application/x-www-form-urlencoded'; + if (is_object(json_decode($token_params))) { + $content_type = 'application/json'; + } + $headers = array( + "Content-Type: {$content_type}", + 'Content-Length: ' . strlen($token_params) + ); + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + curl_setopt($ch, CURLOPT_HEADER, 1); + curl_setopt($ch, CURLOPT_USERPWD, $this->clientID . ":" . $this->clientSecret); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); + curl_setopt($ch, CURLOPT_HEADER, 0); - return json_decode(self::fetchURL($token_endpoint, $token_params)); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); - } + $response = curl_exec($ch); + + if (curl_errno($ch)) { + throw new OpenIDConnectClientException('Curl error: ' . curl_error($ch)); + } + + return json_decode($response); + } /** * @param object $claims @@ -360,12 +405,9 @@ class OpenIDConnectClient } $user_info_endpoint = self::getProviderConfigValue("userinfo_endpoint"); - $schema = 'openid'; - - $user_info_endpoint .= "?schema=" . $schema - . "&access_token=" . $this->accessToken; - $user_json = json_decode(self::fetchURL($user_info_endpoint)); + $headers = array("Authorization: Bearer $this->accessToken"); + $user_json = json_decode(self::fetchURL($user_info_endpoint,null,$headers)); $this->userInfo = $user_json; @@ -384,12 +426,13 @@ class OpenIDConnectClient * @throws OpenIDConnectClientException * @return mixed */ - private function fetchURL($url, $post_body = null) { - + private function fetchURL($url, $post_body = null, $extra_headers = null) { // OK cool - then let's create a new cURL resource handle $ch = curl_init(); + $headers = array(); + // Determine whether this is a GET or POST if ($post_body != null) { curl_setopt($ch, CURLOPT_POST, 1); @@ -403,13 +446,19 @@ class OpenIDConnectClient $content_type = 'application/json'; } - curl_setopt($ch, CURLOPT_HTTPHEADER, array( + $headers = array_merge($headers, array( "Content-Type: {$content_type}", 'Content-Length: ' . strlen($post_body) )); - } + // Extra headers are needed for authorization + if( $extra_headers ) + $headers = array_merge($headers, $extra_headers); + + // Adds any extra headers required in the request + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + // Set URL to download curl_setopt($ch, CURLOPT_URL, $url); @@ -430,6 +479,7 @@ class OpenIDConnectClient curl_setopt($ch, CURLOPT_CAINFO, $this->certPath); } else { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); } // Should cURL return or print out the data? (true = return, false = print) @@ -456,7 +506,7 @@ class OpenIDConnectClient * @throws OpenIDConnectClientException */ public function getProviderURL() { - + if (!isset($this->providerConfig['issuer'])) { throw new OpenIDConnectClientException("The provider URL has not been set"); } else { diff --git a/client_example/auth.php b/client_example/auth.php new file mode 100644 index 00000000..868649f4 --- /dev/null +++ b/client_example/auth.php @@ -0,0 +1,25 @@ +addScope('openid'); + $oidc->addScope('profile'); + $oidc->authenticate(); + $name = $oidc->requestUserInfo('given_name'); + $logout = $oidc->getLogOutURL(); + + $_SESSION['user'] = $name; + $_SESSION['openid_id_token'] = $oidc->getIdToken(); + $_SESSION['openid_logout_url'] = $logout; + } + catch(Exception $e) { + $_SESSION['login_error'] = "OpenAM failed to authorise you. $e->getMessage()"; + } + + header('Location: ./'); +?> diff --git a/client_example/index.php b/client_example/index.php new file mode 100644 index 00000000..48c96edf --- /dev/null +++ b/client_example/index.php @@ -0,0 +1,26 @@ + +