Keycloak — приложение не выходит из системы после единого входа из других приложенийPhp

Кемеровские программисты php общаются здесь
Ответить
Anonymous
 Keycloak — приложение не выходит из системы после единого входа из других приложений

Сообщение Anonymous »

Недавно я работал над проектом на основе PHP, и в нем реализована система входа в систему keycloak sso. Есть 3 приложения (скажем, приложение 1, 2 и 3), которые используют sso. В приложении 1 также реализован выход из обратного канала. Проблема в том, что если приложение 1 в настоящее время выполнено в системе, и я выхожу из приложения 2 или приложения 3 с помощью единого входа, приложение 1 все равно будет входить в систему, даже если сеанс в keycloak уже очищен. Я пытался очистить файл cookie (который имеет два значения: meto и phpsessid), установить и удалить его через серверную часть, но это не сработало.
Это мои настройки выхода из системы
Настройки выхода из системы
Это моя функция выхода из обратного канала и очистки файлов cookie

Код: Выделить всё

function keycloak_backchannel_logout() {
// log_message('d', '=== BACKCHANNEL LOGOUT CALLED ===');
log_message('debug', '=== KEYCLOAK BACKCHANNEL LOGOUT CALLED ===');

// Only accessible if Keycloak is enabled
if (!$this->config->item('keycloak_enabled')) {
show_404();
}

log_message('debug', '=== CONDITION 1 PASS ===');

// Only accept POST requests
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
show_404();
}

log_message('debug', '=== CONDITION 2 PASS ===');

// Enhanced logging: Log IP address and request details
$client_ip = $this->input->ip_address();
$user_agent = $this->input->user_agent();
$request_time = date('Y-m-d H:i:s');

log_message('debug', '=== BACKCHANNEL LOGOUT PROCESS START ===');
log_message('debug', 'Backchannel logout called by Keycloak from IP: ' . $client_ip);
log_message('debug', 'Request time: ' . $request_time);
log_message('debug', 'User-Agent: ' . $user_agent);

// Log all POST data for debugging
$post_data = $this->input->post();
log_message('debug', 'POST data received: ' . json_encode($post_data));

try {
// Get logout_token from POST data
$logout_token = $this->input->post('logout_token');

if (!$logout_token) {
log_message('error', 'Backchannel logout: No logout_token provided');
log_message('error', 'Available POST keys: ' . implode(', ', array_keys($post_data)));
$this->output->set_status_header(400);
$this->output->set_output('Bad Request: Missing logout_token');
return;
}

// Log logout token preview (first 50 chars for security)
log_message('debug', 'Logout token received (preview): ' . substr($logout_token, 0, 50) . '...');

// Decode and validate logout_token
$token_data = $this->decode_logout_token($logout_token);

if (!$token_data) {
log_message('error', 'Backchannel logout: Invalid logout_token - validation failed');
$this->output->set_status_header(400);
$this->output->set_output('Bad Request: Invalid logout_token');
return;
}

// Log token data for debugging
log_message('debug', 'Logout token data: ' . json_encode($token_data));

// Extract session_id from token
$session_id = $token_data['sid'] ?? null;

if (!$session_id) {
log_message('error', 'Backchannel logout: No session_id in logout_token');
log_message('error', 'Available token claims: ' . implode(', ', array_keys($token_data)));
$this->output->set_status_header(400);
$this->output->set_output('Bad Request: No session_id in token');
return;
}

log_message('debug', 'Backchannel logout: Processing session_id: ' .  $session_id);

// Clear current session first (like frontend logout)
$this->session->sess_destroy();
log_message('debug', 'Backchannel logout: Current session destroyed');

// Clear cookies like frontend logout does
$this->clear_keycloak_cookies();
log_message('debug', 'Backchannel logout: Keycloak cookies cleared');

// Also destroy session file by session_id (additional cleanup)
$this->destroy_session_by_id($session_id);

log_message('debug', 'Backchannel logout: Session destroyed successfully for session_id: ' . $session_id);
log_message('debug', '=== BACKCHANNEL LOGOUT COMPLETED ===');

// Return 200 OK to Keycloak
$this->output->set_status_header(200);
$this->output->set_output('OK');

} catch (Exception $e) {
// log_message('error', 'Backchannel logout error: ' . $e->getMessage());
// log_message('error', 'Stack trace: ' . $e->getTraceAsString());

log_message('debug', 'Backchannel logout error: ' . $e->getMessage());
log_message('debug', 'Stack trace: ' . $e->getTraceAsString());

$this->output->set_status_header(500);
$this->output->set_output('Internal Server Error');
}
}

private function clear_keycloak_cookies() {
log_message('info', '=== CLEARING KEYCLOAK COOKIES ===');

// Get cookie domain and path from config
$cookie_domain = $this->config->item('cookie_domain') ?: '';
$cookie_path = $this->config->item('cookie_path') ?: '/';

log_message('debug', 'Cookie domain: ' . $cookie_domain);
log_message('debug', 'Cookie path: ' . $cookie_path);

// List of cookies to clear (based on frontend logout behavior)
$cookies_to_clear = [
'keycloak_id_token',
'keycloak_id_token_exp',
'keycloak_access_token',
'keycloak_refresh_token',
'keycloak_state',
'keycloak_code_verifier',
'keycloak_nonce',
'meeto',
'PHPSESSID',
'user_data',  // This might be the key!
'ci_session'  // CodeIgniter session cookie
];

foreach ($cookies_to_clear as $cookie_name) {
// Clear cookie with different domain/path combinations
$cookie_configs = [
['domain' => $cookie_domain, 'path' => $cookie_path],
['domain' => $cookie_domain, 'path' => '/'],
['domain' => '', 'path' => $cookie_path],
['domain' => '', 'path' => '/'],
['domain' => '.pelindo.test', 'path' => '/'],
['domain' => '.pelindo.test', 'path' => $cookie_path]
];

foreach ($cookie_configs as $config) {
// Set cookie to expire in the past
setcookie($cookie_name, '', time() - 3600, $config['path'], $config['domain'], false, true);

log_message('debug', 'Cleared cookie: ' . $cookie_name . ' (domain: ' . $config['domain'] . ', path: ' . $config['path'] . ')');
}
}

log_message('debug', 'Deleting some of cookies');
delete_cookie('meeto');
delete_cookie('PHPSESSID');

log_message('debug', '=== KEYCLOAK COOKIES CLEARED ===');
}
Будем благодарны за любую помощь.

Подробнее здесь: https://stackoverflow.com/questions/798 ... other-apps
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Php»