Для централизованной авторизации пользователей Webasyst можно подключить внешнюю систему SSO. В этом примере используется Keycloak как провайдер, и библиотека jumbojett/openid-connect-php для реализации протокола OpenID Connect.
1. Установка библиотеки
composer require jumbojett/openid-connect-php
2. Настройка Keycloak
- Создайте клиента в Keycloak.
- Установите:
Client ID
:webasyst
Access Type
:confidential
- Укажите
Valid Redirect URIs
:https://example.com/*
3. Изменение index.php
Webasyst
В начало файла добавлен код авторизации:
session_start();
require_once __DIR__ . '/vendor/autoload.php';
use Jumbojett\OpenIDConnectClient;
Исключения из авторизации:
function isExcludedPath($path) {
$patterns = [
'#^/api/public#',
'#^/favicon.ico$#',
'#^/robots.txt$#'
];
foreach ($patterns as $pattern) {
if (preg_match($pattern, $path)) return true;
}
return false;
}
Обработка выхода:
if (!empty($_GET['logout']) && isset($_SESSION['id_token'])) {
$id_token = $_SESSION['id_token'];
session_destroy();
setcookie(session_name(), '', time() - 3600);
$logout_url = 'https://sso.example.com/realms/realm-name/protocol/openid-connect/logout?' . http_build_query([
'id_token_hint' => $id_token,
'post_logout_redirect_uri' => 'https://example.com'
]);
header('Location: ' . $logout_url);
exit;
}
Авторизация:
$current_path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
if (!isset($_SESSION['user']) && !isExcludedPath($current_path)) {
$oidc = new OpenIDConnectClient(
'https://sso.example.com/realms/realm-name',
'webasyst',
'your_client_secret'
);
$oidc->setRedirectURL('https://example.com');
$oidc->addScope(['openid', 'email', 'profile']);
$oidc->authenticate();
$_SESSION['user'] = [
'email' => $oidc->requestUserInfo('email'),
'name' => $oidc->requestUserInfo('preferred_username'),
];
$_SESSION['id_token'] = $oidc->getIdToken();
}
5. Класс для выхода из SSO
Чтобы вынести логику выхода в отдельный класс, добавьте, например, waSSOAuthPlugin
или используйте любой подходящий для вас плагин/контроллер:
class mySSOAuthActions extends waController
{
const LOGOUT_URL = 'https://sso.example.com/realms/realm-name/protocol/openid-connect/logout?';
const REDIRECT_URI = 'https://example.com';
public function logoutAction()
{
$id_token = $_SESSION['id_token'] ?? null;
session_destroy();
setcookie(session_name(), '', time() - 3600);
if ($id_token) {
$logout_url = self::LOGOUT_URL . http_build_query([
'id_token_hint' => $id_token,
'post_logout_redirect_uri' => self::REDIRECT_URI
]);
header('Location: ' . $logout_url);
} else {
header('Location: ' . self::REDIRECT_URI);
}
exit;
}
}
Теперь для выхода достаточно перейти по ссылке:
/?module=ssoauth&action=logout
6. Автоматическая авторизация Webasyst после входа через SSO
После успешной аутентификации через Keycloak можно сразу авторизовать пользователя в Webasyst. Ниже пример метода execute()
в контроллере, который:
- Получает email из Keycloak;
- Ищет пользователя в Webasyst;
- Авторизует его;
- Перенаправляет в зависимости от группы.
public function execute()
{
require_once wa()->getAppPath('lib/classes/vendor/autoload.php', 'booking');
$email = $_SESSION['user']['email']; // email из Keycloak
// Ищем пользователя по email
$user_model = new waContactModel();
$user = $user_model->getByEmail($email);
if (!$user) {
throw new waException('Пользователь не найден');
}
$user_id = (int) $user['id'];
// Авторизация в Webasyst
$auth = new waAuth();
$auth->auth(['id' => $user_id]);
// Проверка группы (например, админ — group_id = 1)
$groupId = bookingHelper::getGroupId($this->getUser()->getId());
if ($groupId === 1) {
$this->redirect('/webasyst/');
}
// Обработка параметров запроса
$uid = waRequest::param('uid');
$confirmation_whatsapp = waRequest::get('w', 0, 'int');
$confirmation_email = waRequest::get('e', 0, 'int');
// Получаем заказ по UID
$userModel = new bookingUsersModel();
$orderModel = new bookingOrdersModel();
$orderRecord = $orderModel->getByField(['uid' => $uid]);
// Далее — логика обработки заказа...
}
Теперь при успешной аутентификации через Keycloak, Webasyst автоматически узнаёт пользователя и пускает в систему.