From e03638e17ecc8b58bcce5ea7ecddacf59fc5c091 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 3 Sep 2019 10:03:54 -0400 Subject: [PATCH 01/34] getRedirectURL avoid PHP 7.1+ warning on reset() reset() desires a variable --- src/OpenIDConnectClient.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index c4a72889..238b70e2 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -572,8 +572,10 @@ public function getRedirectURL() { ?: @$_SERVER['SERVER_ADDR']; $port = (443 === $port) || (80 === $port) ? '' : ':' . $port; + + $uriSplit = explode("?", $_SERVER['REQUEST_URI']); - return sprintf('%s://%s%s/%s', $protocol, $host, $port, @trim(reset(explode('?', $_SERVER['REQUEST_URI'])), '/')); + return sprintf('%s://%s%s/%s', $protocol, $host, $port, @trim(reset($uriSplit), '/')); } /** From dd44c1ca7e45d35dcd8f32ea503b545149bc6562 Mon Sep 17 00:00:00 2001 From: Jon Erickson Date: Mon, 6 Apr 2020 11:19:18 -0700 Subject: [PATCH 02/34] Removed client ID query parameter when making a token request using Basic Auth. --- CHANGELOG.md | 1 + src/OpenIDConnectClient.php | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc9265f6..fcdced04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed * Fix at_hash verification #200 * Getters for public parameters #204 +* Removed client ID query parameter when making a token request using Basic Auth ### Removed * diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index df4de6ef..28536ffc 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -715,6 +715,7 @@ protected function requestTokens($code) { if (in_array('client_secret_basic', $token_endpoint_auth_methods_supported, true)) { $headers = ['Authorization: Basic ' . base64_encode(urlencode($this->clientID) . ':' . urlencode($this->clientSecret))]; unset($token_params['client_secret']); + unset($token_params['client_id']); } // Convert token params to string format From cf184a41fa362cff02c2c7547563491fabfc944a Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 1 May 2020 11:44:22 -0400 Subject: [PATCH 03/34] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95f88360..d1e49b29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). * Fix indent #e9cdf56 * Cleanup conditional code flow for better readability #107f3fb * Added strict type comparisons #167 + * getRedirectURL() will not log a warning for PHP 7.1+ ### Removed * From 840572c4e5112945152b85c799189acf3797edfa Mon Sep 17 00:00:00 2001 From: Kieran Foxley-Jones <2211195+KieranFJ@users.noreply.github.com> Date: Tue, 7 Jul 2020 11:04:19 +0100 Subject: [PATCH 04/34] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e08ef15a..97061044 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). * Fix at_hash verification #200 * Getters for public parameters #204 * Removed client ID query parameter when making a token request using Basic Auth +* Added scope parameter to refresh token request ### Removed * Removed explicit content-length header - caused issues with proxy servers From 45808a447921a5a254834dc5c994477d9362e7e3 Mon Sep 17 00:00:00 2001 From: Kieran Foxley-Jones <2211195+KieranFJ@users.noreply.github.com> Date: Tue, 7 Jul 2020 11:09:05 +0100 Subject: [PATCH 05/34] Add scope to refreshToken request Some providers require a scope when requesting a token refresh. Uses the same process as requestResourceOwnerToken() due to the RFC requiring the scope to be the same for an access_token request and for a refresh token request --- src/OpenIDConnectClient.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index 2872e711..b5360031 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -743,6 +743,7 @@ public function refreshToken($refresh_token) { 'refresh_token' => $refresh_token, 'client_id' => $this->clientID, 'client_secret' => $this->clientSecret, + 'scope' => implode(' ', $this->scopes), ); // Convert token params to string format From 43d4c96774d2a73289a790b3b93ce8854a3b470c Mon Sep 17 00:00:00 2001 From: Kieran Foxley-Jones <2211195+KieranFJ@users.noreply.github.com> Date: Tue, 7 Jul 2020 11:10:05 +0100 Subject: [PATCH 06/34] Update OpenIDConnectClient.php --- src/OpenIDConnectClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index b5360031..3b11b9e5 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -743,7 +743,7 @@ public function refreshToken($refresh_token) { 'refresh_token' => $refresh_token, 'client_id' => $this->clientID, 'client_secret' => $this->clientSecret, - 'scope' => implode(' ', $this->scopes), + 'scope' => implode(' ', $this->scopes), ); // Convert token params to string format From 8b1d15be8b009166cf388d56f6f23a114c27ec4b Mon Sep 17 00:00:00 2001 From: Namo Date: Tue, 7 Jul 2020 21:23:19 -0400 Subject: [PATCH 07/34] Added cURL error code to existing error message This should make the cURL error message easier to debug, especially for those occasions where `curl_error()` just returns NULL :) --- src/OpenIDConnectClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index 2872e711..bb78ae76 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -1141,7 +1141,7 @@ protected function fetchURL($url, $post_body = null, $headers = array()) { $this->responseCode = $info['http_code']; if ($output === false) { - throw new OpenIDConnectClientException('Curl error: ' . curl_error($ch)); + throw new OpenIDConnectClientException('Curl error: (' . curl_errno($ch) . ') ' . curl_error($ch)); } // Close the cURL resource, and free system resources From 8509ec2e93a2de6117b873c1eec80b492422c386 Mon Sep 17 00:00:00 2001 From: Luc Chauvin Date: Thu, 23 Jul 2020 15:44:44 +0200 Subject: [PATCH 08/34] Add support for MS Azure Active Directory B2C user flows see : https://docs.microsoft.com/en-us/azure/active-directory-b2c/user-flow-overview --- CHANGELOG.md | 2 +- src/OpenIDConnectClient.php | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e08ef15a..522c2f41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Added -* +* Add support for MS Azure Active Directory B2C user flows ### Changed * Fix at_hash verification #200 diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index bb78ae76..f13f6eaf 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -184,6 +184,12 @@ class OpenIDConnectClient */ private $wellKnown = false; + /** + * @var mixed holds well-known opendid configuration parameters, like policy for MS Azure AD B2C User Flow + * @see https://docs.microsoft.com/en-us/azure/active-directory-b2c/user-flow-overview + */ + private $wellKnownConfigParameters = array(); + /** * @var int timeout (seconds) */ @@ -500,6 +506,9 @@ private function getWellKnownConfigValue($param, $default = null) { // This is also known as auto "discovery" if(!$this->wellKnown) { $well_known_config_url = rtrim($this->getProviderURL(), '/') . '/.well-known/openid-configuration'; + if (count($this->wellKnownConfigParameters) > 0){ + $well_known_config_url .= '?' . http_build_query($this->wellKnownConfigParameters) ; + } $this->wellKnown = json_decode($this->fetchURL($well_known_config_url)); } @@ -520,6 +529,16 @@ private function getWellKnownConfigValue($param, $default = null) { throw new OpenIDConnectClientException("The provider {$param} could not be fetched. Make sure your provider has a well known configuration available."); } + /** + * Set optionnal parameters for .well-known/openid-configuration + * + * @param string $param + * + */ + public function setWellKnownConfigParameters(array $params = []){ + $this->wellKnownConfigParameters=$params; + } + /** * @param string $url Sets redirect URL for auth flow From 7f5940c0beed4723e017bffbf7dbe2539851b40c Mon Sep 17 00:00:00 2001 From: JuliusPC Date: Mon, 27 Jul 2020 09:33:23 +0200 Subject: [PATCH 09/34] use random_bytes instead of uniqid for token generation; added random_compat library for php < 7 --- composer.json | 3 ++- src/OpenIDConnectClient.php | 11 ++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index ae8ef23a..bc1b6b44 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,8 @@ "php": ">=5.4", "phpseclib/phpseclib" : "~2.0", "ext-json": "*", - "ext-curl": "*" + "ext-curl": "*", + "paragonie/random_compat": ">=2" }, "require-dev": { "phpunit/phpunit": "^4.8", diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index 2872e711..2cb465f6 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -580,9 +580,18 @@ public function getRedirectURL() { * Used for arbitrary value generation for nonces and state * * @return string + * @throws OpenIDConnectClientException */ protected function generateRandString() { - return md5(uniqid(rand(), TRUE)); + // Error and Exception need to be catched in this order, see https://github.com/paragonie/random_compat/blob/master/README.md + // random_compat polyfill library should be removed if support for PHP versions < 7 is dropped + try { + return \bin2hex(\random_bytes(16)); + } catch (Error $e) { + throw new OpenIDConnectClientException('Random token generation failed.'); + } catch (Exception $e) { + throw new OpenIDConnectClientException('Random token generation failed.'); + }; } /** From dc963615943a206a3acc338fc1ccc1ea0f6e616b Mon Sep 17 00:00:00 2001 From: JuliusPC Date: Mon, 27 Jul 2020 11:30:20 +0200 Subject: [PATCH 10/34] Use of `random_bytes()` --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e08ef15a..846db912 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). * Fix at_hash verification #200 * Getters for public parameters #204 * Removed client ID query parameter when making a token request using Basic Auth +* Use of `random_bytes()` for token generation instead of `uniqid()`; polyfill for PHP < 7.0 provided. ### Removed * Removed explicit content-length header - caused issues with proxy servers From 9f15504105640b03277d7174b62fbfc0f5e608ab Mon Sep 17 00:00:00 2001 From: Michael Jett Date: Thu, 27 Aug 2020 12:47:41 -0400 Subject: [PATCH 11/34] Prepping for release --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 522c2f41..23e3d8d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [Unreleased] +## [0.9.1] ### Added * Add support for MS Azure Active Directory B2C user flows From ce972309057b3cf1967ba559346e9d6d3d667503 Mon Sep 17 00:00:00 2001 From: nikosev Date: Thu, 29 Oct 2020 14:22:46 +0200 Subject: [PATCH 12/34] Add support for PKCE --- CHANGELOG.md | 5 +++ README.md | 14 +++++++ src/OpenIDConnectClient.php | 78 +++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23e3d8d0..7d6eca88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [Unreleased] + +### Added +* Support for [PKCE](https://tools.ietf.org/html/rfc7636). Currentlly the supported methods are 'plain' and 'S256'. + ## [0.9.1] ### Added diff --git a/README.md b/README.md index 8ea18a9d..7044f216 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,20 @@ if (!$data->active) { ``` +## Example 8: PKCE Client ## + +```php +use Jumbojett\OpenIDConnectClient; + +$oidc = new OpenIDConnectClient('https://id.provider.com', + 'ClientIDHere', + null); +$oidc->setCodeChallengeMethod('S256'); +$oidc->authenticate(); +$name = $oidc->requestUserInfo('given_name'); + +``` + ## Development Environments ## In some cases you may need to disable SSL security on on your development systems. diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index f13f6eaf..2b3f11e1 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -226,6 +226,17 @@ class OpenIDConnectClient protected $enc_type = PHP_QUERY_RFC1738; + /** + * @var string holds code challenge method for PKCE mode + * @see https://tools.ietf.org/html/rfc7636 + */ + private $codeChallengeMethod = false; + + /** + * @var array holds PKCE supported algorithms + */ + private $pkceAlgs = array('S256' => 'sha256', 'plain' => false); + /** * @param $provider_url string optional * @@ -640,6 +651,21 @@ private function requestAuthorization() { $auth_params = array_merge($auth_params, array('response_type' => implode(' ', $this->responseTypes))); } + // If the client supports Proof Key for Code Exchange (PKCE) + if (!empty($this->getCodeChallengeMethod()) && in_array($this->getCodeChallengeMethod(), $this->getProviderConfigValue('code_challenge_methods_supported'))) { + $codeVerifier = bin2hex(random_bytes(64)); + $this->setCodeVerifier($codeVerifier); + if (!empty($this->pkceAlgs[$this->getCodeChallengeMethod()])) { + $codeChallenge = rtrim(strtr(base64_encode(hash($this->pkceAlgs[$this->getCodeChallengeMethod()], $codeVerifier, true)), '+/', '-_'), '='); + } else { + $codeChallenge = $codeVerifier; + } + $auth_params = array_merge($auth_params, array( + 'code_challenge' => $codeChallenge, + 'code_challenge_method' => $this->getCodeChallengeMethod() + )); + } + $auth_endpoint .= (strpos($auth_endpoint, '?') === false ? '?' : '&') . http_build_query($auth_params, null, '&', $this->enc_type); $this->commitSession(); @@ -737,6 +763,15 @@ protected function requestTokens($code) { unset($token_params['client_id']); } + if (!empty($this->getCodeVerifier())) { + $headers = []; + unset($token_params['client_secret']); + $token_params = array_merge($token_params, array( + 'client_id' => $this->clientID, + 'code_verifier' => $this->getCodeVerifier() + )); + } + // Convert token params to string format $token_params = http_build_query($token_params, null, '&', $this->enc_type); @@ -1579,6 +1614,35 @@ protected function unsetState() { $this->unsetSessionKey('openid_connect_state'); } + /** + * Stores $codeVerifier + * + * @param string $codeVerifier + * @return string + */ + protected function setCodeVerifier($codeVerifier) { + $this->setSessionKey('openid_connect_code_verifier', $codeVerifier); + return $codeVerifier; + } + + /** + * Get stored codeVerifier + * + * @return string + */ + protected function getCodeVerifier() { + return $this->getSessionKey('openid_connect_code_verifier'); + } + + /** + * Cleanup state + * + * @return void + */ + protected function unsetCodeVerifier() { + $this->unsetSessionKey('openid_connect_code_verifier'); + } + /** * Get the response code from last action/curl request. * @@ -1732,4 +1796,18 @@ public function getLeeway() { return $this->leeway; } + + /** + * @return string + */ + public function getCodeChallengeMethod() { + return $this->codeChallengeMethod; + } + + /** + * @param string $codeChallengeMethod + */ + public function setCodeChallengeMethod($codeChallengeMethod) { + $this->codeChallengeMethod = $codeChallengeMethod; + } } From bca40d14ae580fa7bd3e2f243d0ca6a7983d4d2f Mon Sep 17 00:00:00 2001 From: nikosev Date: Mon, 2 Nov 2020 19:38:45 +0200 Subject: [PATCH 13/34] Fix "Undefined index:openid_connect_code_verifier" --- src/OpenIDConnectClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index 2b3f11e1..188c33f9 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -763,7 +763,7 @@ protected function requestTokens($code) { unset($token_params['client_id']); } - if (!empty($this->getCodeVerifier())) { + if (!empty($this->getCodeChallengeMethod()) && !empty($this->getCodeVerifier())) { $headers = []; unset($token_params['client_secret']); $token_params = array_merge($token_params, array( From 5b17a572de1b188d777c7c090d020274cb0c3220 Mon Sep 17 00:00:00 2001 From: nikosev Date: Mon, 2 Nov 2020 19:40:46 +0200 Subject: [PATCH 14/34] Require paragonie/random_compat library --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index ae8ef23a..4c1612ae 100644 --- a/composer.json +++ b/composer.json @@ -5,6 +5,7 @@ "require": { "php": ">=5.4", "phpseclib/phpseclib" : "~2.0", + "paragonie/random_compat":"2.0.19", "ext-json": "*", "ext-curl": "*" }, From 721a96e2d6b474a402114c1d6408137e713ecc27 Mon Sep 17 00:00:00 2001 From: nikosev Date: Mon, 2 Nov 2020 20:07:14 +0200 Subject: [PATCH 15/34] Fix typo in CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d6eca88..6541bc0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Added -* Support for [PKCE](https://tools.ietf.org/html/rfc7636). Currentlly the supported methods are 'plain' and 'S256'. +* Support for [PKCE](https://tools.ietf.org/html/rfc7636). Currently the supported methods are 'plain' and 'S256'. ## [0.9.1] From 4f95102af87f86c43e8191ec6e90d9f35ed1ce5f Mon Sep 17 00:00:00 2001 From: Michael Jett Date: Mon, 16 Nov 2020 09:48:22 -0500 Subject: [PATCH 16/34] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b4a8835..3185924c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [Unreleased] +## [0.9.2] ### Added * Support for [PKCE](https://tools.ietf.org/html/rfc7636). Currently the supported methods are 'plain' and 'S256'. From 024cbf0e45a2d90cc8a049385b06878501cfed4a Mon Sep 17 00:00:00 2001 From: JuliusPC Date: Sat, 5 Dec 2020 12:48:17 +0100 Subject: [PATCH 17/34] remove duplicate paragonie/random_compat dependency --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index 9c52f558..bc1b6b44 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,6 @@ "require": { "php": ">=5.4", "phpseclib/phpseclib" : "~2.0", - "paragonie/random_compat":"2.0.19", "ext-json": "*", "ext-curl": "*", "paragonie/random_compat": ">=2" From 698bc5954c10e3ba7dd5ffd9a607692d60e57aa8 Mon Sep 17 00:00:00 2001 From: JuliusPC Date: Sat, 5 Dec 2020 16:38:10 +0100 Subject: [PATCH 18/34] add get/setHttpUpgradeInsecureRequests(), fixes #174 --- CHANGELOG.md | 5 +++++ README.md | 8 +++++++- src/OpenIDConnectClient.php | 25 ++++++++++++++++++++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3185924c..93eab569 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## master + +### Added +* it is now possible to disable upgrading from HTTP to HTTPS for development purposes by calling `setHttpUpgradeInsecureRequests(false)` + ## [0.9.2] ### Added diff --git a/README.md b/README.md index 7044f216..9a3baca4 100644 --- a/README.md +++ b/README.md @@ -153,10 +153,16 @@ $oidc->setVerifyHost(false); $oidc->setVerifyPeer(false); ``` +Also, your local system might not support HTTPS, so you might disable uprading to it: + +```php +$oidc->httpUpgradeInsecureRequests(false); +``` + ### Todo ### - Dynamic registration does not support registration auth tokens and endpoints [1]: http://openid.net/specs/openid-connect-basic-1_0-15.html#id_res ## Contributing ### - - All pull requests, once merged, should be added to the changelog.md file. + - All pull requests, once merged, should be added to the CHANGELOG.md file. diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index ee81b02c..eb04496b 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -226,6 +226,11 @@ class OpenIDConnectClient protected $enc_type = PHP_QUERY_RFC1738; + /** + * @var bool Enable or disable upgrading to HTTPS by paying attention to HTTP header HTTP_UPGRADE_INSECURE_REQUESTS + */ + protected $httpUpgradeInsecureRequests = true; + /** * @var string holds code challenge method for PKCE mode * @see https://tools.ietf.org/html/rfc7636 @@ -585,7 +590,7 @@ public function getRedirectURL() { * Support of 'ProxyReverse' configurations. */ - if (isset($_SERVER['HTTP_UPGRADE_INSECURE_REQUESTS']) && ($_SERVER['HTTP_UPGRADE_INSECURE_REQUESTS'] === '1')) { + if ($this->httpUpgradeInsecureRequests && isset($_SERVER['HTTP_UPGRADE_INSECURE_REQUESTS']) && ($_SERVER['HTTP_UPGRADE_INSECURE_REQUESTS'] === '1')) { $protocol = 'https'; } else { $protocol = @$_SERVER['HTTP_X_FORWARDED_PROTO'] @@ -1292,6 +1297,16 @@ public function setVerifyHost($verifyHost) { $this->verifyHost = $verifyHost; } + + /** + * Controls whether http header HTTP_UPGRADE_INSECURE_REQUESTS should be considered + * defaults to true + * @param bool $httpUpgradeInsecureRequests + */ + public function setHttpUpgradeInsecureRequests($httpUpgradeInsecureRequests) { + $this->httpUpgradeInsecureRequests = $httpUpgradeInsecureRequests; + } + /** * @return bool */ @@ -1308,6 +1323,14 @@ public function getVerifyPeer() return $this->verifyPeer; } + /** + * @return bool + */ + public function getHttpUpgradeInsecureRequests() + { + return $this->httpUpgradeInsecureRequests; + } + /** * Use this for custom issuer validation * The given function should accept the issuer string from the JWT claim as the only argument From 10a8fe54c3d869a4dbbb4e8f10d416a24855ab57 Mon Sep 17 00:00:00 2001 From: Michael Couillard Date: Sat, 5 Dec 2020 11:28:48 -0500 Subject: [PATCH 19/34] removed a leftover from conflict resolution; whitespace fix --- CHANGELOG.md | 3 --- src/OpenIDConnectClient.php | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eab8a143..8d7ecdc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,9 +56,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). * Added strict type comparisons #167 * Bugfix: required `openid` scope was omitted when additional scopes were registered using `addScope` method. This resulted in failing OpenID process. -### Removed -* - ## [0.8.0] ### Added diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index 80880706..d6430c3c 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -603,7 +603,7 @@ public function getRedirectURL() { $port = (443 === $port) || (80 === $port) ? '' : ':' . $port; - $uriSplit = explode("?", $_SERVER['REQUEST_URI']); + $uriSplit = explode("?", $_SERVER['REQUEST_URI']); return sprintf('%s://%s%s/%s', $protocol, $host, $port, @trim(reset($uriSplit), '/')); } From c4d45cbc4ccbda110d45b4cc2a704fe411c8afbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Sj=C3=B6str=C3=B6m?= Date: Tue, 9 Mar 2021 10:56:00 +0100 Subject: [PATCH 20/34] Check if session key exists before accessing it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I ran into this issue when trying to set up a basic OAuth flow using this library and Keycloak. The issue was introduced by ce97230 which checks for PKCE support, the way it does this is to call the function getCodeVerifier() which in turn calls getSessionKey() which returns a specified key from _SESSION. This will fail when setting up a client without PKCE because the key will not exist. With this commit a sanity check is introduced which first checks if the key exists in _SESSION before returning it, otherwise just returning false. This should not affect existing library functionality. Signed-off-by: Erik Sjöström --- src/OpenIDConnectClient.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index ee81b02c..f55ba28f 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -1733,7 +1733,10 @@ protected function commitSession() { protected function getSessionKey($key) { $this->startSession(); - return $_SESSION[$key]; + if (array_key_exists($key, $_SESSION)) { + return $_SESSION[$key]; + } + return false; } protected function setSessionKey($key, $value) { From ac71a4c3eece3a176a84456afd34fc808391a75d Mon Sep 17 00:00:00 2001 From: Ingo Dittmar Date: Wed, 14 Apr 2021 15:28:55 +0200 Subject: [PATCH 21/34] Fix php5.4 empty-bug --- src/OpenIDConnectClient.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index ee81b02c..5ca8317b 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -661,7 +661,8 @@ private function requestAuthorization() { } // If the client supports Proof Key for Code Exchange (PKCE) - if (!empty($this->getCodeChallengeMethod()) && in_array($this->getCodeChallengeMethod(), $this->getProviderConfigValue('code_challenge_methods_supported'))) { + $ccm = $this->getCodeChallengeMethod(); // php5.4 fix, see https://stackoverflow.com/a/4328049 + if (!empty($ccm) && in_array($this->getCodeChallengeMethod(), $this->getProviderConfigValue('code_challenge_methods_supported'))) { $codeVerifier = bin2hex(random_bytes(64)); $this->setCodeVerifier($codeVerifier); if (!empty($this->pkceAlgs[$this->getCodeChallengeMethod()])) { @@ -772,7 +773,9 @@ protected function requestTokens($code) { unset($token_params['client_id']); } - if (!empty($this->getCodeChallengeMethod()) && !empty($this->getCodeVerifier())) { + $ccm = $this->getCodeChallengeMethod(); // php5.4 fix, see https://stackoverflow.com/a/4328049 + $cv = $this->getCodeVerifier(); // php5.4 fix, see https://stackoverflow.com/a/4328049 + if (!empty($ccm) && !empty($cv)) { $headers = []; unset($token_params['client_secret']); $token_params = array_merge($token_params, array( From 79915d0b34bf0f33135caf557d6cdbe603bf262b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zden=C4=9Bk=20Zaho=C5=99?= Date: Wed, 12 May 2021 16:52:13 +0200 Subject: [PATCH 22/34] Prevent notice "Only variables can be passed by reference" [Fixes #261] --- src/OpenIDConnectClient.php | 3 ++- tests/OpenIDConnectClientTest.php | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/OpenIDConnectClientTest.php diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index ee81b02c..06cd83ac 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -603,7 +603,8 @@ public function getRedirectURL() { $port = (443 === $port) || (80 === $port) ? '' : ':' . $port; - return sprintf('%s://%s%s/%s', $protocol, $host, $port, @trim(reset(explode('?', $_SERVER['REQUEST_URI'])), '/')); + $explodedRequestUri = isset($_SERVER['REQUEST_URI']) ? explode('?', $_SERVER['REQUEST_URI']) : []; + return sprintf('%s://%s%s/%s', $protocol, $host, $port, trim(reset($explodedRequestUri), '/')); } /** diff --git a/tests/OpenIDConnectClientTest.php b/tests/OpenIDConnectClientTest.php new file mode 100644 index 00000000..e08efea8 --- /dev/null +++ b/tests/OpenIDConnectClientTest.php @@ -0,0 +1,20 @@ +getRedirectURL()); + + $_SERVER['SERVER_NAME'] = 'domain.test'; + $_SERVER['REQUEST_URI'] = '/path/index.php?foo=bar&baz#fragment'; + self::assertSame('http://domain.test/path/index.php', $client->getRedirectURL()); + } +} From 92533ec42974790b12d2f996eb00249b23744c9a Mon Sep 17 00:00:00 2001 From: olivier Date: Mon, 5 Jul 2021 14:34:24 +0200 Subject: [PATCH 23/34] Auth basic for requestResourceOwnerToken added --- src/OpenIDConnectClient.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index ee81b02c..bbc76d23 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -715,7 +715,7 @@ public function requestClientCredentialsToken() { * @return mixed * @throws OpenIDConnectClientException */ - public function requestResourceOwnerToken($bClientAuth = FALSE) { + public function requestResourceOwnerToken($bClientAuth = FALSE) { $token_endpoint = $this->getProviderConfigValue('token_endpoint'); $headers = []; @@ -731,8 +731,13 @@ public function requestResourceOwnerToken($bClientAuth = FALSE) { //For client authentication include the client values if($bClientAuth) { - $post_data['client_id'] = $this->clientID; - $post_data['client_secret'] = $this->clientSecret; + $token_endpoint_auth_methods_supported = $this->getProviderConfigValue('token_endpoint_auth_methods_supported', ['client_secret_basic']); + if (in_array('client_secret_basic', $token_endpoint_auth_methods_supported, true)) { + $headers = ['Authorization: Basic ' . base64_encode(urlencode($this->clientID) . ':' . urlencode($this->clientSecret))]; + } else { + $post_data['client_id'] = $this->clientID; + $post_data['client_secret'] = $this->clientSecret; + } } // Convert token params to string format From 29e2abcb1f5e8baa6f9fcf8fb6320f9e21fdfbc0 Mon Sep 17 00:00:00 2001 From: Olivier JARRY Date: Mon, 5 Jul 2021 14:48:01 +0200 Subject: [PATCH 24/34] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 9c52f558..5bbfe36b 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "jumbojett/openid-connect-php", + "name": "aureolebigben/openid-connect-php", "description": "Bare-bones OpenID Connect client", "license": "Apache-2.0", "require": { From fc5ad50c22e7bcdc80c6d179b9a69b8a0429e064 Mon Sep 17 00:00:00 2001 From: Olivier JARRY Date: Mon, 5 Jul 2021 15:05:48 +0200 Subject: [PATCH 25/34] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5bbfe36b..9c52f558 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "aureolebigben/openid-connect-php", + "name": "jumbojett/openid-connect-php", "description": "Bare-bones OpenID Connect client", "license": "Apache-2.0", "require": { From eaeb52064ec9dd0fe96b20df0f076b743fa9df63 Mon Sep 17 00:00:00 2001 From: Eloi Rivard Date: Fri, 1 Oct 2021 16:53:12 +0200 Subject: [PATCH 26/34] verifyJWTclaims: fixed an exception when $accessToken is null --- src/OpenIDConnectClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index ee81b02c..7ed05bb5 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -1004,7 +1004,7 @@ protected function verifyJWTclaims($claims, $accessToken = null) { && ($claims->nonce === $this->getNonce()) && ( !isset($claims->exp) || ((gettype($claims->exp) === 'integer') && ($claims->exp >= time() - $this->leeway))) && ( !isset($claims->nbf) || ((gettype($claims->nbf) === 'integer') && ($claims->nbf <= time() + $this->leeway))) - && ( !isset($claims->at_hash) || $claims->at_hash === $expected_at_hash ) + && ( !isset($claims->at_hash) || !isset($accessToken) || $claims->at_hash === $expected_at_hash ) ); } From 24b7bd6a1be48e4d2a5e3e7b627f94590336e84c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Sat, 20 Nov 2021 18:01:24 +0100 Subject: [PATCH 27/34] Removed some comments --- src/OpenIDConnectClient.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index c7dc9011..72646a42 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -666,7 +666,7 @@ private function requestAuthorization() { } // If the client supports Proof Key for Code Exchange (PKCE) - $ccm = $this->getCodeChallengeMethod(); // php5.4 fix, see https://stackoverflow.com/a/4328049 + $ccm = $this->getCodeChallengeMethod(); if (!empty($ccm) && in_array($this->getCodeChallengeMethod(), $this->getProviderConfigValue('code_challenge_methods_supported'))) { $codeVerifier = bin2hex(random_bytes(64)); $this->setCodeVerifier($codeVerifier); @@ -778,8 +778,8 @@ protected function requestTokens($code) { unset($token_params['client_id']); } - $ccm = $this->getCodeChallengeMethod(); // php5.4 fix, see https://stackoverflow.com/a/4328049 - $cv = $this->getCodeVerifier(); // php5.4 fix, see https://stackoverflow.com/a/4328049 + $ccm = $this->getCodeChallengeMethod(); + $cv = $this->getCodeVerifier(); if (!empty($ccm) && !empty($cv)) { $headers = []; unset($token_params['client_secret']); From 2fcbc64d9b50ad436537cc13cc43c04a1faa723d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Sat, 20 Nov 2021 18:09:05 +0100 Subject: [PATCH 28/34] Changelog --- CHANGELOG.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa12eadf..5074140e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] -* getRedirectURL() will not log a warning for PHP 7.1+ -* it is now possible to disable upgrading from HTTP to HTTPS for development purposes by calling `setHttpUpgradeInsecureRequests(false)` +* getRedirectURL() will not log a warning for PHP 7.1+ #179 +* it is now possible to disable upgrading from HTTP to HTTPS for development purposes by calling `setHttpUpgradeInsecureRequests(false)` #241 +* bugfix in verifyJWTclaims when $accessToken is empty and $claims->at_hash is not #276 +* bugfix with the `empty` function in PHP 5.4 #267 ## [0.9.2] @@ -16,7 +18,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [0.9.1] ### Added -* Add support for MS Azure Active Directory B2C user flows +* Add support for MS Azure Active Directory B2C user flows ### Changed * Fix at_hash verification #200 From 56aa80e010ce5eae437d016a6cf04c9dd44763ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Sat, 20 Nov 2021 18:19:29 +0100 Subject: [PATCH 29/34] Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5074140e..f470d4b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] * getRedirectURL() will not log a warning for PHP 7.1+ #179 * it is now possible to disable upgrading from HTTP to HTTPS for development purposes by calling `setHttpUpgradeInsecureRequests(false)` #241 +* bugfix in getSessionKey when _SESSION key does not exist #251 * bugfix in verifyJWTclaims when $accessToken is empty and $claims->at_hash is not #276 * bugfix with the `empty` function in PHP 5.4 #267 From 4ef5208d849f0a029abda9db1188b3bf8d6cf6bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Sat, 20 Nov 2021 18:27:58 +0100 Subject: [PATCH 30/34] Changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca1ce834..4291f103 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). * getRedirectURL() will not log a warning for PHP 7.1+ #179 * it is now possible to disable upgrading from HTTP to HTTPS for development purposes by calling `setHttpUpgradeInsecureRequests(false)` #241 * bugfix in getSessionKey when _SESSION key does not exist #251 - Added scope parameter to refresh token request #255 +* Added scope parameter to refresh token request #225 * bugfix in verifyJWTclaims when $accessToken is empty and $claims->at_hash is not #276 * bugfix with the `empty` function in PHP 5.4 #267 From 47506dd9f16ac30e5caab5a22cedc20e2a6eb665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Sat, 20 Nov 2021 18:40:06 +0100 Subject: [PATCH 31/34] unit tests with GHA --- .github/workflows/build.yml | 38 +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..d8b82623 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,38 @@ +--- +name: build + +on: [push, pull_request] + +env: + DEFAULT_COMPOSER_FLAGS: "--prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi" + +jobs: + phpunit: + name: PHP ${{ matrix.php }} on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + php: ['5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4'] + + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: Cache composer dependencies + uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + - name: Install dependencies + run: composer update $DEFAULT_COMPOSER_FLAGS + - name: Run unit tests + run: vendor/bin/phpunit --verbose --colors=always tests From 556803a71f292b5f3d7fa6a22efe946b4de80ff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Sat, 20 Nov 2021 18:45:05 +0100 Subject: [PATCH 32/34] Version 0.9.3 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4291f103..5c3786c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [Unreleased] +## [0.9.3] * getRedirectURL() will not log a warning for PHP 7.1+ #179 * it is now possible to disable upgrading from HTTP to HTTPS for development purposes by calling `setHttpUpgradeInsecureRequests(false)` #241 * bugfix in getSessionKey when _SESSION key does not exist #251 From 3a0c3a502881de75e157e928bb1b8de1a8eeed7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Sat, 20 Nov 2021 18:46:53 +0100 Subject: [PATCH 33/34] Changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c3786c9..047d6002 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [0.9.3] + +### Added + * getRedirectURL() will not log a warning for PHP 7.1+ #179 * it is now possible to disable upgrading from HTTP to HTTPS for development purposes by calling `setHttpUpgradeInsecureRequests(false)` #241 * bugfix in getSessionKey when _SESSION key does not exist #251 From 712bab2401bb98d2983b1b814c3e569ada472e0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Sun, 21 Nov 2021 17:55:22 +0100 Subject: [PATCH 34/34] Changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 047d6002..97736df2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [unreleased] + +### Added + +* Basic auth support for requestResourceOwnerToken #271 + ## [0.9.3] ### Added