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

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

Сообщение Anonymous »

Недавно я работал над проектом на основе PHP, и в нем реализована система входа в систему Keycloak SSO.
Есть три приложения (скажем, App-1, App-2 и App-3), которые используют SSO. В приложении 1 также реализован выход из обратного канала.
Проблема в том, что если приложение 1 в настоящее время выполнено в системе, и я делаю единый вход из приложения 2 или приложения 3, приложение 1 все равно будет входить в систему, даже если сеанс в Keycloak уже очищен.
Я пытался очистить файл cookie (который имеет два значения meeto и 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»