diff --git a/src/App/KeycloakAuth.php b/src/App/KeycloakAuth.php index e8820f9f..10bde8c9 100644 --- a/src/App/KeycloakAuth.php +++ b/src/App/KeycloakAuth.php @@ -214,10 +214,8 @@ final class KeycloakAuth public function redirectUri(): string { $path = (string) ($this->config['redirect_path'] ?? '/auth/callback'); - $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http'; - $host = (string) ($_SERVER['HTTP_HOST'] ?? 'localhost'); - return $scheme . '://' . $host . $path; + return $this->requestOrigin() . $path; } public function baseUrl(): string @@ -266,10 +264,52 @@ final class KeycloakAuth private function postLogoutRedirectUri(): string { - $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http'; - $host = (string) ($_SERVER['HTTP_HOST'] ?? 'localhost'); + return $this->requestOrigin() . '/auth/login'; + } - return $scheme . '://' . $host . '/auth/login'; + private function requestOrigin(): string + { + $forwardedProto = trim((string) ($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '')); + $forwardedHost = trim((string) ($_SERVER['HTTP_X_FORWARDED_HOST'] ?? '')); + $forwardedPort = trim((string) ($_SERVER['HTTP_X_FORWARDED_PORT'] ?? '')); + + $scheme = $this->normalizeForwardedValue($forwardedProto); + + if ($scheme === '') { + $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http'; + } + + $host = $this->normalizeForwardedValue($forwardedHost); + + if ($host === '') { + $host = (string) ($_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? 'localhost'); + } + + if ($forwardedPort !== '') { + $port = $this->normalizeForwardedValue($forwardedPort); + $hostWithoutPort = preg_replace('/:\d+$/', '', $host) ?? $host; + + if ( + $port !== '' + && !str_contains($host, ':') + && !(($scheme === 'https' && $port === '443') || ($scheme === 'http' && $port === '80')) + ) { + $host = $hostWithoutPort . ':' . $port; + } + } + + return $scheme . '://' . $host; + } + + private function normalizeForwardedValue(string $value): string + { + if ($value === '') { + return ''; + } + + $first = trim(explode(',', $value)[0] ?? ''); + + return strtolower($first); } /**