redirect_uri = \Yii::$app->params['portal'] . '/' . \Yii::$app->language . '/user/checkout/'; $this->metadata_url = \Yii::$app->params['id_server'] . '/realms/' . \Yii::$app->params['realm'] . '/.well-known/openid-configuration'; $this->client_id = \Yii::$app->params['id_server_client_id']; $this->client_secret = \Yii::$app->params['id_server_client_secret']; } public function authenticationServerCheckout() { $metadata = $this->http($this->metadata_url); if (!isset($_GET['code'])) { $_SESSION['state_public'] = bin2hex(random_bytes(5)); $_SESSION['code_verifier_public'] = bin2hex(random_bytes(50)); $code_challenge = $this->base64_urlencode(hash('sha256', $_SESSION['code_verifier_public'], true)); $authorize_url = $metadata->authorization_endpoint . '?' . http_build_query([ 'response_type' => 'code', 'client_id' => $this->client_id, 'redirect_uri' => $this->redirect_uri, 'state' => $_SESSION['state_public'], 'scope' => 'openid profile', 'code_challenge' => $code_challenge, 'code_challenge_method' => 'S256', ]); header("Location: $authorize_url"); exit; } else { if ($_SESSION['state_public'] != $_GET['state']) { die('Authorization server returned an invalid state parameter'); } if (isset($_GET['error'])) { die('Authorization server returned an error: ' . htmlspecialchars($_GET['error'])); } $response = $this->http($metadata->token_endpoint, [ 'grant_type' => 'authorization_code', 'code' => $_GET['code'], 'redirect_uri' => $this->redirect_uri, 'client_id' => $this->client_id, 'client_secret' => $this->client_secret, 'code_verifier' => $_SESSION['code_verifier_public'], ]); if (!isset($response->access_token)) { die('Error fetching access token'); } $userinfo = $this->http($metadata->userinfo_endpoint, [ 'access_token' => $response->access_token, ]); if (isset($userinfo->group_membership)) { if (in_array('/public_user', $userinfo->group_membership)) { if ($userinfo->sub) { Auth::checkUserExists($userinfo->preferred_username); $_SESSION['sub'] = $userinfo->sub; $_SESSION['profile'] = $userinfo; Auth::setUser($userinfo->preferred_username); $user = Auth::getUser(); if ($user) { $user->open_id = $userinfo->sub; $user->save(); UserSession::log('public', 1, $userinfo->sub); } $_SESSION['id_token_hint'] = $response->id_token; header('Location: ' . \Yii::$app->goToAction('user')); exit; } } else { Ts::set([202, 218, 73]); $roles = !empty($userinfo->realm_access) && $userinfo->realm_access->roles ? $userinfo->realm_access->roles : []; $session_type = (in_array('superAdmin', $roles)) ? 'admin' : 'partner'; UserSession::log($session_type, 2, $userinfo->sub); $_SESSION['register_user'] = $userinfo->sub; $_SESSION['id_token_hint'] = $response->id_token; header('Location: ' . \Yii::$app->goHome()); exit; } } else { Ts::set([203]); \Yii::$app->flash('error', Ts::get(203)); header('Location: ' . \Yii::$app->goHome()); exit; } } } private function http($url, $params = false) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); if ($params) curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params)); return json_decode(curl_exec($ch)); } private function base64_urlencode($string) { return rtrim(strtr(base64_encode($string), '+/', '-_'), '='); } }