apereo / phpCAS

Apereo PHP CAS Client
https://apereo.github.io/phpCAS/
Apache License 2.0
794 stars 396 forks source link

PGTiou, proxies, certificate issue #344

Closed Cyazd closed 4 years ago

Cyazd commented 4 years ago

Hi to everybody,

I'm at the moment struggling with CAS and phpCAS examples. My aim is to test/play with the proxy files.

I have two CAS server in Tomcat, a Jasig 3.5.2 and a Apereo 5.3.14 and I'm on windows 10.

I first tried the "example_service.php" file with the 3.5.2. CAS version. Everything was going well.

Then I tried "example_proxy_serviceWeb.php" and since then I'm in a maelstrom of issues.

But it still doesn't work...

So, please, please, please, help me ! Thanking you in advance.

example_service.php

<?php
require_once 'config.php';
require_once $phpcas_path . '/CAS.php';
phpCAS::setDebug();
phpCAS::setVerbose(true);

phpCAS::client(CAS_VERSION_2_0, $cas_host, $cas_port, $cas_context);

phpCAS::setCasServerCACert($cas_server_ca_cert_path);

phpCAS::forceAuthentication();

print '<h1>I am a service that can be proxied.</h1>';
require 'script_info.php';
echo '<p>The user\'s login is <b>' . phpCAS::getUser() . '</b>.</p>';
if (!isset($_SESSION['n'])) {
    $_SESSION['n'] = 0;
}
echo '<p>request #' . (++$_SESSION['n']) . '</p>';
?>

config.php

<?php
$phpcas_path = 'vendor/jasig/phpcas';
$cas_host = 'localhost';
$cas_context = '/cas2';
$cas_port = 8443;

$cas_server_ca_cert_path = 'etc/cas/ssl/certificat_CAS.crt';

// The "real" hosts of clustered cas server that send SAML logout messages
// Assumes the cas server is load balanced across multiple hosts
$cas_real_hosts = array('cas-real-1.example.com', 'cas-real-2.example.com');

// Client config for cookie hardening
$client_domain = '127.0.0.1';
$client_path = 'phpcas';
$client_secure = true;
$client_httpOnly = true;
$client_lifetime = 0;

// Database config for PGT Storage
$db = 'pgsql:host=localhost;dbname=phpcas';
//$db = 'mysql:host=localhost;dbname=phpcas';
$db_user = 'phpcasuser';
$db_password = 'mysupersecretpass';
$db_table = 'phpcastabel';
$driver_options = '';

///////////////////////////////////////////
// End Configuration -- Don't edit below //
///////////////////////////////////////////

// Generating the URLS for the local cas example services for proxy testing
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
    $curbase = 'https://' . $_SERVER['SERVER_NAME'];
} else {
    $curbase = 'http://' . $_SERVER['SERVER_NAME'];
}
if ($_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443) {
    $curbase .= ':' . $_SERVER['SERVER_PORT'];
}

$curdir = dirname($_SERVER['REQUEST_URI']) . "/";

// CAS client nodes for rebroadcasting pgtIou/pgtId and logoutRequest
$rebroadcast_node_1 = 'http://localhost/CAS_clientproxy/example_service.php';
$rebroadcast_node_2 = 'http://localhost/CAS_clientproxy/example_service.php';

// access to a single service
$serviceUrl = $curbase . $curdir . 'example_service.php';
// access to a second service
$serviceUrl2 = $curbase . $curdir . 'example_service_that_proxies.php';

$pgtBase = preg_quote(preg_replace('/^http:/', 'https:', $curbase . $curdir), '/');
$pgtUrlRegexp = '/^' . $pgtBase . '.*$/';

$cas_url = 'https://' . $cas_host;
if ($cas_port != '443') {
    $cas_url = $cas_url . ':' . $cas_port;
}
$cas_url = $cas_url . $cas_context;

// Set the session-name to be unique to the current script so that the client script
// doesn't share its session with a proxied script.
// This is just useful when running the example code, but not normally.
session_name(
    'session_for:'
    . preg_replace('/[^a-z0-9-]/i', '_', basename($_SERVER['SCRIPT_NAME']))
);
// Set an UTF-8 encoding header for internation characters (User attributes)
header('Content-Type: text/html; charset=utf-8');
?>

application.yml

server:
  port: 8443
  ssl:
    key-store: file:///C:/etc/cas/ssl/CAS_keystore.jks
    key-store-password: changeit
    key-password: changeit    

cas:
  serviceRegistry:
    json:
      location: file:///C:/etc/cas/services

log for example_service.php

E910 .START (2020-04-10 13:25:18) phpCAS-1.3.8 ****************** [CAS.php:475]
E910 .=> phpCAS::client('2.0', 'localhost', 8443, '/cas2') [example_service.php:28]
E910 .|    => CAS_Client::__construct('2.0', false, 'localhost', 8443, '/cas2', true) [CAS.php:365]
E910 .|    |    Starting a new session p5ldg1qhu3l8melqpun7ikequ0 [Client.php:932]
E910 .|    |    Session is not authenticated [Client.php:938]
E910 .|    <= ''
E910 .<= ''
E910 .=> phpCAS::setCasServerCACert('etc/cas/ssl/certificat_CAS.crt') [example_service.php:32]
E910 .<= ''
E910 .=> phpCAS::forceAuthentication() [example_service.php:80]
E910 .|    => CAS_Client::forceAuthentication() [CAS.php:1120]
E910 .|    |    => CAS_Client::isAuthenticated() [Client.php:1286]
E910 .|    |    |    => CAS_Client::_wasPreviouslyAuthenticated() [Client.php:1398]
E910 .|    |    |    |    no user found [Client.php:1640]
E910 .|    |    |    <= false
E910 .|    |    |    no ticket found [Client.php:1499]
E910 .|    |    <= false
E910 .|    |    => CAS_Client::redirectToCas(false) [Client.php:1295]
E910 .|    |    |    => CAS_Client::getServerLoginURL(false, false) [Client.php:1661]
E910 .|    |    |    |    => CAS_Client::getURL() [Client.php:342]
E910 .|    |    |    |    |    Final URI: https://localhost/CAS_clientproxy/example_service.php [Client.php:3585]
E910 .|    |    |    |    <= 'https://localhost/CAS_clientproxy/example_service.php'
E910 .|    |    |    <= 'https://localhost:8443/cas2/login?service=https%3A%2F%2Flocalhost%2FCAS_clientproxy%2Fexample_service.php'
E910 .|    |    |    Redirect to : https://localhost:8443/cas2/login?service=https%3A%2F%2Flocalhost%2FCAS_clientproxy%2Fexample_service.php [Client.php:1668]
E910 .|    |    |    exit()
E910 .|    |    |    -
E910 .|    |    -
E910 .|    -
7600 .START (2020-04-10 13:25:18) phpCAS-1.3.8 ****************** [CAS.php:475]
7600 .=> phpCAS::client('2.0', 'localhost', 8443, '/cas2') [example_service.php:28]
7600 .|    => CAS_Client::__construct('2.0', false, 'localhost', 8443, '/cas2', true) [CAS.php:365]
7600 .|    |    Starting a new session p5ldg1qhu3l8melqpun7ikequ0 [Client.php:932]
7600 .|    |    Session is not authenticated [Client.php:938]
7600 .|    |    Ticket 'ST-9-Q1MJ-dRvr0Qau-bw-P5239glw1wISAAC' found [Client.php:1026]
7600 .|    <= ''
7600 .<= ''
7600 .=> phpCAS::setCasServerCACert('etc/cas/ssl/certificat_CAS.crt') [example_service.php:32]
7600 .<= ''
7600 .=> phpCAS::forceAuthentication() [example_service.php:80]
7600 .|    => CAS_Client::forceAuthentication() [CAS.php:1120]
7600 .|    |    => CAS_Client::isAuthenticated() [Client.php:1286]
7600 .|    |    |    => CAS_Client::_wasPreviouslyAuthenticated() [Client.php:1398]
7600 .|    |    |    |    no user found [Client.php:1640]
7600 .|    |    |    <= false
7600 .|    |    |    CAS 2.0 ticket `ST-9-Q1MJ-dRvr0Qau-bw-P5239glw1wISAAC' is present [Client.php:1451]
7600 .|    |    |    => CAS_Client::validateCAS20('', NULL, NULL, false) [Client.php:1454]
7600 .|    |    |    |     [Client.php:3216]
7600 .|    |    |    |    => CAS_Client::getServerServiceValidateURL() [Client.php:3222]
7600 .|    |    |    |    |    => CAS_Client::getURL() [Client.php:453]
7600 .|    |    |    |    |    |    Final URI: https://localhost/CAS_clientproxy/example_service.php [Client.php:3585]
7600 .|    |    |    |    |    <= 'https://localhost/CAS_clientproxy/example_service.php'
7600 .|    |    |    |    <= 'https://localhost:8443/cas2/serviceValidate?service=https%3A%2F%2Flocalhost%2FCAS_clientproxy%2Fexample_service.php'
7600 .|    |    |    |    => CAS_Client::_readURL('https://localhost:8443/cas2/serviceValidate?service=https%3A%2F%2Flocalhost%2FCAS_clientproxy%2Fexample_service.php&ticket=ST-9-Q1MJ-dRvr0Qau-bw-P5239glw1wISAAC', NULL, NULL, NULL) [Client.php:3237]
7600 .|    |    |    |    |    => CAS_Request_CurlRequest::sendRequest() [AbstractRequest.php:242]
7600 .|    |    |    |    |    |    CURL: Set CURLOPT_CAINFO etc/cas/ssl/certificat_CAS.crt [CurlRequest.php:129]
7600 .|    |    |    |    |    |    curl_exec() failed [CurlRequest.php:77]
7600 .|    |    |    |    |    <= false
7600 .|    |    |    |    <= false
7600 .|    |    |    |    could not open URL 'https://localhost:8443/cas2/serviceValidate?service=https%3A%2F%2Flocalhost%2FCAS_clientproxy%2Fexample_service.php&ticket=ST-9-Q1MJ-dRvr0Qau-bw-P5239glw1wISAAC' to validate (CURL error #77: error setting certificate verify locations:
7600 .|    |    |    |      CAfile: etc/cas/ssl/certificat_CAS.crt
7600 .|    |    |    |      CApath: none) [Client.php:3239]
7600 .|    |    |    |    => CAS_AuthenticationException::__construct(CAS_Client, 'Ticket not validated', 'https://localhost:8443/cas2/serviceValidate?service=https%3A%2F%2Flocalhost%2FCAS_clientproxy%2Fexample_service.php&ticket=ST-9-Q1MJ-dRvr0Qau-bw-P5239glw1wISAAC', true) [Client.php:3243]
7600 .|    |    |    |    |    => CAS_Client::getURL() [AuthenticationException.php:77]
7600 .|    |    |    |    |    <= 'https://localhost/CAS_clientproxy/example_service.php'
7600 .|    |    |    |    |    CAS URL: https://localhost:8443/cas2/serviceValidate?service=https%3A%2F%2Flocalhost%2FCAS_clientproxy%2Fexample_service.php&ticket=ST-9-Q1MJ-dRvr0Qau-bw-P5239glw1wISAAC [AuthenticationException.php:80]
7600 .|    |    |    |    |    Authentication failure: Ticket not validated [AuthenticationException.php:81]
7600 .|    |    |    |    |    Reason: no response from the CAS server [AuthenticationException.php:83]
7600 .|    |    |    |    |    exit()
7600 .|    |    |    |    |    -
7600 .|    |    |    |    -
7600 .|    |    |    -
7600 .|    |    -
7600 .|    -
phy25 commented 4 years ago

I may not be able to help much since I don't quite use the PGT part, but I am not sure why you use $cas_server_ca_cert_path = 'etc/cas/ssl/certificat_CAS.crt'; instead of something like $cas_server_ca_cert_path = 'C:/etc/cas/ssl/certificat_CAS.crt'; (looks like you are running on Windows).

jfritschi commented 4 years ago

I can see curl certificate errors in the debug log. @phy25 suggestions is correct. You have to set a certificate or disable any validation (not recommended for production). What you also need to do is make sure your CAS server trust the SSL certificate of your phpCAS application (usually an issue if you use self signed certificates or you have wrong setup) . A proxy ticket will only be transmitted over a trusted SSL channel ( part of the security model). If you do not have a proper SSL setup this will not work... You need to pay attention to a valid SSL setup and closely monitor the error logs of both server if you start playing with proxy mode... These are advanced uses cases...

Cyazd commented 4 years ago

Thanks to you two for your answers.

I stopped working locally and got a VPS. Seemed like indeed it was a certificate issue.

I can't remember clearly if I was using the right certificate back when I was working locally, but getting appropriate certificate from Let's Encrypt without changing the config.php nor the index.php worked on my VPS.

Anyway, thanks for your help !