From 99d7d75082d565ac1698ba6f78a185e3c12ca655 Mon Sep 17 00:00:00 2001 From: ChristianMaidhof Date: Sun, 21 Jul 2024 23:33:29 +0200 Subject: [PATCH 1/2] Save Oauth2 Access Token in User Meta MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now, the Access Token and Refresh Token are stored in the database. After login, the tokens are encrypted using the login key of the WordPress system and stored as usermeta in the database as “encrypted_token”. Before logout, the corresponding entry is removed from the metadata. The token can then be used by other plugins, e.g., for calling APIs. --- authorizer.php | 2 + src/authorizer/class-authentication.php | 27 +++++++ src/authorizer/class-save-secure.php | 99 +++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 src/authorizer/class-save-secure.php diff --git a/authorizer.php b/authorizer.php index 67c32a62..3866dc1d 100644 --- a/authorizer.php +++ b/authorizer.php @@ -36,6 +36,8 @@ require_once __DIR__ . '/src/authorizer/class-authentication.php'; require_once __DIR__ . '/src/authorizer/class-authorization.php'; require_once __DIR__ . '/src/authorizer/class-login-form.php'; +require_once __DIR__ . '/src/authorizer/class-save-secure.php'; + require_once __DIR__ . '/src/authorizer/class-dashboard-widget.php'; require_once __DIR__ . '/src/authorizer/class-ajax-endpoints.php'; require_once __DIR__ . '/src/authorizer/class-sync-userdata.php'; diff --git a/src/authorizer/class-authentication.php b/src/authorizer/class-authentication.php index e68bf111..7879914c 100644 --- a/src/authorizer/class-authentication.php +++ b/src/authorizer/class-authentication.php @@ -12,6 +12,7 @@ use Authorizer\Helper; use Authorizer\Options; use Authorizer\Authorization; +use Authorizer\Save_Secure; /** * Implements the authentication (is user who they say they are?) features of @@ -137,6 +138,7 @@ public function custom_authenticate( $user, $username, $password ) { $externally_authenticated_emails = array(); $authenticated_by = ''; $result = null; + $encrypted_token = ''; // Try OAuth2 authentication if it's enabled and we don't have a // successful login yet. @@ -153,6 +155,10 @@ public function custom_authenticate( $user, $username, $password ) { $externally_authenticated_emails[] = $result['email']; } $authenticated_by = $result['authenticated_by']; + + if (isset($result['encrypted_token'])){ + $encrypted_token = $result['encrypted_token']; + } } } @@ -294,6 +300,10 @@ public function custom_authenticate( $user, $username, $password ) { $user = $result; } + if ($encrypted_token != ''){ + update_user_meta( $user->ID, 'encrypted_token', $encrypted_token ); + } + // If we haven't exited yet, we have a valid/approved user, so authenticate them. return $user; } @@ -309,6 +319,9 @@ public function custom_authenticate( $user, $username, $password ) { * or null if not attempting an oauth2 login. */ protected function custom_authenticate_oauth2( $auth_settings ) { + $encrypted_token = ''; //Maybe the access token from oauth2 service, encrypted + + // Move on if oauth2 hasn't been requested here. // phpcs:ignore WordPress.Security.NonceVerification if ( empty( $_GET['external'] ) || 'oauth2' !== $_GET['external'] ) { @@ -563,6 +576,14 @@ function ( $entry ) { $token = $provider->getAccessToken( 'authorization_code', array( 'code' => $_REQUEST['code'], ) ); + + $token_json_prepared = $token->jsonSerialize(); + $token_json = json_encode($token_json_prepared); + + $save_secure = new Save_Secure; + $encrypted_token = $save_secure->encrypt($token_json); + + } catch ( \Exception $e ) { // Failed to get token; try again from the beginning. $auth_url = $provider->getAuthorizationUrl( @@ -663,6 +684,7 @@ function ( $entry ) { 'authenticated_by' => 'oauth2', 'oauth2_provider' => $auth_settings['oauth2_provider'], 'oauth2_attributes' => $attributes, + 'encrypted_token' => $encrypted_token, ); } @@ -1397,6 +1419,11 @@ public function pre_logout() { if ( empty( self::$authenticated_by ) && ! empty( $_REQUEST['external'] ) ) { self::$authenticated_by = $_REQUEST['external']; } + + $user_id = get_current_user_id(); + //Delete token from usermeta + delete_user_meta( $user_id, 'encrypted_token'); + } /** diff --git a/src/authorizer/class-save-secure.php b/src/authorizer/class-save-secure.php new file mode 100644 index 00000000..2d04a0b9 --- /dev/null +++ b/src/authorizer/class-save-secure.php @@ -0,0 +1,99 @@ +key = $this->get_default_key(); + $this->salt = $this->get_default_salt(); + } + + // encrypt and decrypt methods omitted for readability. + + private function get_default_key() + { + + if (defined('LOGGED_IN_KEY') && '' !== LOGGED_IN_KEY) { + return LOGGED_IN_KEY; + } + + // If this is reached, you're either not on a live site or have a serious security issue. + return 'no-secret-key'; + } + + private function get_default_salt() + { + + if (defined('LOGGED_IN_SALT') && '' !== LOGGED_IN_SALT) { + return LOGGED_IN_SALT; + } + + // If this is reached, you're either not on a live site or have a serious security issue. + return 'no-secret-salt'; + } + + + /** + * Encypts a value for storing in database + */ + public function encrypt($value) + { + if (!extension_loaded('openssl')) { + return $value; + } + + $method = 'aes-256-ctr'; + $ivlen = openssl_cipher_iv_length($method); + $iv = openssl_random_pseudo_bytes($ivlen); + + $raw_value = openssl_encrypt($value . $this->salt, $method, $this->key, 0, $iv); + if (!$raw_value) { + return false; + } + + return base64_encode($iv . $raw_value); + } + + + /** + * Decrypts a value + */ + public function decrypt($raw_value) + { + if (!extension_loaded('openssl')) { + return $raw_value; + } + + $raw_value = base64_decode($raw_value, true); + + $method = 'aes-256-ctr'; + $ivlen = openssl_cipher_iv_length($method); + $iv = substr($raw_value, 0, $ivlen); + + $raw_value = substr($raw_value, $ivlen); + + $value = openssl_decrypt($raw_value, $method, $this->key, 0, $iv); + if (!$value || substr($value, -strlen($this->salt)) !== $this->salt) { + return false; + } + + return substr($value, 0, -strlen($this->salt)); + } +} From 907986742c2d551a2050985281b28f99827443e0 Mon Sep 17 00:00:00 2001 From: ChristianMaidhof Date: Sun, 21 Jul 2024 23:37:53 +0200 Subject: [PATCH 2/2] Update class-authentication.php --- src/authorizer/class-authentication.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/authorizer/class-authentication.php b/src/authorizer/class-authentication.php index 7879914c..4a4dba63 100644 --- a/src/authorizer/class-authentication.php +++ b/src/authorizer/class-authentication.php @@ -301,6 +301,7 @@ public function custom_authenticate( $user, $username, $password ) { } if ($encrypted_token != ''){ + //Save the Access Token in user_meta for later use, f.e in other Plugins update_user_meta( $user->ID, 'encrypted_token', $encrypted_token ); }