CAS 5.2 single sign out does not work for SAML 1.1 phpCAS clients

602 views
Skip to first unread message

Viacheslav Babanin

unread,
Apr 23, 2018, 10:05:20 AM4/23/18
to CAS Community
Hello, I have encountered issue with SSO for SAML 1.1 clients with CAS 5.2

I am rather new cas user and probably i am missing something obvious.

I am using folowing phpCAS client:

<?php
require_once 'phpcas/source/CAS.php';
// Enable debugging
phpCAS::setDebug('phpCAS.log');
// Enable verbose error messages. Disable in production!
phpCAS::setVerbose(true);
// Initialize phpCAS
$cas_host = 'cas-1.uek.krakow.pl';
// Context of the CAS Server
$cas_context = '/cas';
// Port of your CAS server. Normally for a https server it's 443
$cas_port = 443;
phpCAS::client(SAML_VERSION_1_1, $cas_host, $cas_port, $cas_context);
// For production use set the CA certificate that is the issuer of the cert
// on the CAS server and uncomment the line below
// phpCAS::setCasServerCACert($cas_server_ca_cert_path);
// For quick testing you can disable SSL validation of the CAS server.
// THIS SETTING IS NOT RECOMMENDED FOR PRODUCTION.
// VALIDATING THE CAS SERVER IS CRUCIAL TO THE SECURITY OF THE CAS PROTOCOL!
phpCAS::setNoCasServerValidation();
// force CAS authentication

$cas_real_hosts = array('cas-1.uek.krakow.pl');


phpCAS::handleLogoutRequests(true, $cas_real_hosts);

phpCAS::forceAuthentication();
// at this step, the user has been authenticated by the CAS server
// and the user's login name can be read with phpCAS::getUser().
// logout if desired
// logout if desired
if (isset($_REQUEST['logout'])) {
    phpCAS::logout();
}
?>
<html>
<head>
        <title>Advanced SAML 1.1 example</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<h2>Advanced SAML 1.1 example</h2>
<?php require 'script_info.php' ?>

Authentication succeeded for user
<strong><?php echo phpCAS::getUser(); ?></strong>.
User has attributes
<strong><?php  if(phpCAS::hasAttributes()){
    echo 'true';
    }
    else {
    echo 'false';
    }

    ?></strong>.
<h3>User Attributes</h3>
<ul>
    <?php
    foreach (phpCAS::getAttributes() as $key => $value) {
        if (is_array($value)) {
            echo '<li>', $key, ':<ol>';
            foreach ($value as $item) {
                echo '<li><strong>', $item, '</strong></li>';
            }
            echo '</ol></li>';
        } else {
            echo '<li>', $key, ': <strong>', $value, '</strong></li>' . PHP_EOL;
        }
    }
    ?>
</ul>
<p><a href="?logout=">Logout</a></p>
</body>
</html>


Single sign in works like expected. If I have several CAS clients, when I log in to one of them, I am authenticated in all, like expected.

But Single Logout completely doesn't work for me. When I log out using CAS logout endpoint "{cas-server}/cas/logout" i receive message that I am logged out from CAS and I can see in SSO manager that CAS Session is terminated.
But all application sessions are still alive, I am allowed not only to navigate client pages but also close\open tabs and I am still logged in.

I have tried to configure service with client application with both "BACK_CHANNEL" and "FRONT_CHANNEL" logoutType with no luck.

1. If I use BACK_CHANNEL.

Thats how service definition looks like:

{
  "@class" : "org.jasig.cas.services.RegexRegisteredService",
  "serviceId" : "https://cas-client.ssl.stub/",
  "name" : "example_simple_citest",
  "id" : 7,
  "logoutType" : "BACK_CHANNEL",

  "attributeReleasePolicy" : {
    "@class" : "org.apereo.cas.services.ReturnMappedAttributeReleasePolicy",
    "allowedAttributes" : {
      "@class" : "java.util.TreeMap",
      "uid" : "user_id",
        "sn" : "surname"
         }
        }
      }


When I log out using "{cas-server}/cas/logout" endpoint CAS server log looks like this: back.txt (see attachment)

phpCAS.log doesn't log anything in this case. And application session still lives untill I close browser.

2. If I use FRONT_CHANNEL.

Thats how service definition looks like:

{
  "@class" : "org.jasig.cas.services.RegexRegisteredService",
  "serviceId" : "https://cas-client.ssl.stub/",
  "name" : "example_simple_citest",
  "id" : 7,
  "logoutType" : "FRONT_CHANNEL",

  "attributeReleasePolicy" : {
    "@class" : "org.apereo.cas.services.ReturnMappedAttributeReleasePolicy",
    "allowedAttributes" : {
      "@class" : "java.util.TreeMap",
      "uid" : "user_id",
        "sn" : "surname"
         }
        }
      }

When I log out using "{cas-server}/cas/logout" endpoint CAS server log looks like this: front.txt (see attachment)

And I see following message upon logout on endpoint page:




W

Which tells me that logout notification has been sent.

At the same time, when endpoint logout happens, phpCAS.log logs following message.

D0EE .START (2018-04-23 15:37:16) phpCAS-1.3.5 ****************** [CAS.php:468]
D0EE .=> phpCAS::client('S1', 'cas-1.server.test.pl', 443, '/cas') [index.php:13]
D0EE .|    => CAS_Client::__construct('S1', false, 'cas-1.server.test.pl', 443, '/cas', true) [CAS.php:360]
D0EE .|    |    Starting a new session ST-26-6Ad0C8OCIF5n-1zWgmiE8HZdw-E-v-cas-1 [Client.php:932]
D0EE .|    |    Session is authenticated as: babanin [Client.php:936]
D0EE .|    <= ''
D0EE .<= ''
D0EE .=> phpCAS::setNoCasServerValidation() [index.php:20]
D0EE .|    You have configured no validation of the legitimacy of the cas server. This is not recommended for production use. [CAS.php:1644]
D0EE .<= ''
D0EE .=> CAS_Client::handleLogoutRequests(true, array (  0 => 'cas-1.server.test.pl',)) [CAS.php:1276]
D0EE .|    Not a logout request [Client.php:1739]
D0EE .<= ''
D0EE .=> phpCAS::forceAuthentication() [index.php:27]
D0EE .|    => CAS_Client::forceAuthentication() [CAS.php:1098]
D0EE .|    |    => CAS_Client::isAuthenticated() [Client.php:1280]
D0EE .|    |    |    => CAS_Client::_wasPreviouslyAuthenticated() [Client.php:1393]
D0EE .|    |    |    |    user = `babanin' [Client.php:1622]
D0EE .|    |    |    <= true
D0EE .|    |    |    user was already authenticated, no need to look for tickets [Client.php:1417]
D0EE .|    |    <= true
D0EE .|    |    no need to authenticate [Client.php:1282]
D0EE .|    <= true
D0EE .<= ''

This message looks exactly like regular login message, but it appers when tab with application is closed and at the exact time when CAS sends logout notification.
It seems like client receives FRONT_CHANNEL connection from server but fails to recognise it as logout request.


So, summarising:

Logging out from cas using both endpoint and casified applications causes CAS to terminate SSO session but fails to terminate application sessions.
As a client I am using example code from phpCAS documentation.
Please help me to solve this issue, or, atlease get understanding of it.

Thank you very much for attention,

Viacheslav Babanin
back.txt
front.txt

Man H

unread,
Apr 23, 2018, 10:25:18 AM4/23/18
to cas-...@apereo.org
Logout requests are handled by clients.

.=> CAS_Client::handleLogoutRequests(true, array (  0 => 'cas-1.server.test.pl',)) [CAS.php:1276]
D0EE .|    Not a logout request [Client.php:1739]

See phpcas
--
- Website: https://apereo.github.io/cas
- Gitter Chatroom: https://gitter.im/apereo/cas
- List Guidelines: https://goo.gl/1VRrw7
- Contributions: https://goo.gl/mh7qDG
---
You received this message because you are subscribed to the Google Groups "CAS Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cas-user+unsubscribe@apereo.org.
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/33b216d7-1947-4ffd-8bc7-51f307b6bd3a%40apereo.org.

Viacheslav Babanin

unread,
Apr 23, 2018, 10:33:09 AM4/23/18
to CAS Community
Could you elaborate, please?

Quoting official documentation at https://wiki.jasig.org/display/casc/phpcas+examples

"By default phpCAS by default only handles requests that emanate from the CAS host exclusively (declared in phpCAS::client() or phpCAS::proxy()). Failure to restrict SAML logout requests to authorized hosts could allow denial of service attacks where at the least the server is tied up parsing bogus XML messages.

To disable access control on logout requests, use: 

phpCAS::handleLogoutRequests(false);

The hosts allowed to send logout requests can also be passed in an array which might be usefull in with clustered cas servers:

phpCAS::handleLogoutRequests(true, array("server1.domain.edu", "server2.domain.edu"));

"

As i understand, it should be enough either to use phpCAS::handleLogoutRequests(false); (which I tried and it seems like it has no impact) or to specify cas server which is allowed to send logout requests in an array (which I did in example above).




понедельник, 23 апреля 2018 г., 16:25:18 UTC+2 пользователь Manfredo Hopp написал:
To unsubscribe from this group and stop receiving emails from it, send an email to cas-user+u...@apereo.org.

Viacheslav Babanin

unread,
Apr 23, 2018, 10:41:10 AM4/23/18
to CAS Community
That's how phpCAS.log looks if i provide it with phpCAS::handleLogoutRequests(false);

DA64 .=> phpCAS::client('S1', 'cas-1.server.test.pl', 443, '/cas') [index.php:13]
DA64 .|    => CAS_Client::__construct('S1', false, 'cas-1.server.test.pl', 443, '/cas', true) [CAS.php:360]
DA64 .|    |    Starting a new session ST-27-xTftALKF-XM9TG94QFnab2R5994-v-cas-1 [Client.php:932]
DA64 .|    |    Session is authenticated as: babanin [Client.php:936]
DA64 .|    <= ''
DA64 .<= ''
DA64 .=> phpCAS::setNoCasServerValidation() [index.php:20]
DA64 .|    You have configured no validation of the legitimacy of the cas server. This is not recommended for production use. [CAS.php:1644]
DA64 .<= ''
DA64 .=> CAS_Client::handleLogoutRequests(false, false) [CAS.php:1276]
DA64 .|    Not a logout request [Client.php:1739]
DA64 .<= ''
DA64 .=> phpCAS::forceAuthentication() [index.php:27]
DA64 .|    => CAS_Client::forceAuthentication() [CAS.php:1098]
DA64 .|    |    => CAS_Client::isAuthenticated() [Client.php:1280]
DA64 .|    |    |    => CAS_Client::_wasPreviouslyAuthenticated() [Client.php:1393]
DA64 .|    |    |    |    user = `babanin' [Client.php:1622]
DA64 .|    |    |    <= true
DA64 .|    |    |    user was already authenticated, no need to look for tickets [Client.php:1417]
DA64 .|    |    <= true
DA64 .|    |    no need to authenticate [Client.php:1282]
DA64 .|    <= true
DA64 .<= ''


понедельник, 23 апреля 2018 г., 16:33:09 UTC+2 пользователь Viacheslav Babanin написал:

Ray Bon

unread,
Apr 23, 2018, 12:35:17 PM4/23/18
to cas-...@apereo.org
Viacheslav,

You will want to have handleLogoutRequests(true) so that logout is handled. While testing, skip the CAS server array, just in case the network config changes the apparent source of the request.

Put this in your CAS log4j2.xml to see what happens on CAS side of things:

        <!-- DEBUG service status and logout process and a lot of details -->
        <AsyncLogger name="org.apereo.cas.logout" level="debug" />
        <!-- INFO  Performing logout operations for [TGT-...]
                   [number] logout requests were processed
             DEBUG ST, principal and URL -->
        <AsyncLogger name="org.apereo.cas.logout.DefaultLogoutManager" level="debug">
            <Filters>
                <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="NEUTRAL" />
                <RegexFilter regex="Captured logout request.*" onMismatch="DENY" />
            </Filters>
        </AsyncLogger>
        <!-- DEBUG Logout request will be sent to but does not print anything when login was through SAML 1.1 -->
        <AsyncLogger name="org.apereo.cas.logout.DefaultSingleLogoutServiceLogoutUrlBuilder" level="debug" />
        <!-- DEBUG preparing, processing and logout with URL and ST -->
        <AsyncLogger name="org.apereo.cas.logout.DefaultSingleLogoutServiceMessageHandler" level="debug" />
        <!-- DEBUG SAML logout payload -->
        <AsyncLogger name="org.apereo.cas.logout.SamlCompliantLogoutMessageCreator" level="debug" />

Ray
-- 
Ray Bon
Programmer analyst
Development Services, University Systems
2507218831 | CLE 019 | rb...@uvic.ca

Viacheslav Babanin

unread,
Apr 24, 2018, 3:07:53 AM4/24/18
to CAS Community
Ray,

I have set handleLogoutRequests(true) and added those Loggers to CAS log4j2.xml, restarted CAS server in tomcat and nothing changes, and it seems in log like its publishing logout request but no details.
That's exactyly what I did:

1. Added Loggers to CAS log4j2.xml
2. Restarted CAS in tomcat
3. Set handleLogoutRequests(true) in my saml client.
4. Open incognite mode in Chrome browser.
6. CAS login page shows up. I logged in.
7. Opened new tab with {cas-server}/cas/logout . Got message that I am successfully logged out.
8. Refreshed tab with client. I am still logged in. phpCAS log says that user is already authenticated no reason to authenticate. Application session still lives.

I have tried it both with BACK_CHANNEL and FRONT_CHANNEL set as a logoutType attributes in service definition.

I am attaching logs from CAS.

Thanks, 
Viacheslav



понедельник, 23 апреля 2018 г., 18:35:17 UTC+2 пользователь rbon написал:
front.txt
back.txt

Viacheslav Babanin

unread,
Apr 24, 2018, 6:27:02 AM4/24/18
to CAS Community
It seems like I have a problem witch CAS 5.2.3 and SAML logout requests. Single logout doesn't work and from the logs it seems like CAS constructs SAML logout request but not actually sends it. I am using examplary phpCAS client from docs and when i go to ${cas-server}/cas/logout endpoint in there is nothing in phpCAS logs. If I use THE SAME client. only changing cas endpoint and protocol, with cas 4.1.9 (not configured by me but i have administrator access to it) everything works great and phpCAS actually gets logout request and correctly processes it. What should i look into? Please help.


понедельник, 23 апреля 2018 г., 18:35:17 UTC+2 пользователь rbon написал:
Viacheslav,

Man H

unread,
Apr 24, 2018, 9:16:32 AM4/24/18
to cas-...@apereo.org
Do you have saml support dependency
To unsubscribe from this group and stop receiving emails from it, send an email to cas-user+unsubscribe@apereo.org.
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/d47843c7-3245-4367-8c7f-d457180c5221%40apereo.org.

Man H

unread,
Apr 24, 2018, 9:45:33 AM4/24/18
to cas-...@apereo.org

Ray Bon

unread,
Apr 24, 2018, 12:42:19 PM4/24/18
to cas-...@apereo.org
Check your Apache access.log to see if the request is getting through.
I see this when CAS sends logout request:

2018-04-24T09:32:57.816-07:00 lo...@z.comp.uvic.ca local2.notice httpd[2310]: access: coursespaces2d.uvic.ca: 111.104.118.193 - - [24/Apr/2018:09:32:57 -0700] "POST /login/logout.php HTTP/1.1" 200 26 "-" "Apache-HttpClient/4.5.3 (Java/1.8.0_121)" "__utma=-; __utmb=-; __utmc=-; __utmk=-; __utmx=-; __utmz=-;"

Ray

Man H

unread,
Apr 24, 2018, 1:09:17 PM4/24/18
to cas-...@apereo.org
from your log
2018-04-24 08:59:48,360 DEBUG [org.apereo.cas.logout.SamlCompliantLogoutMessageCreator] - <Generated logout message: [<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="LR-3-ERN1ZJGXY-JGjGfB---2avgK" Version="2.0" IssueInstant="2018-04-24T08:59:48Z"><saml:NameID xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">@NOT_USED@</saml:NameID><samlp:SessionIndex>ST-3-PppjmWz1yAHPFrZwFNMCRW5wsvI-v-cas-1</samlp:SessionIndex></samlp:LogoutRequest>]>

its SAML2 whereas your client is SAML1

To unsubscribe from this group and stop receiving emails from it, send an email to cas-user+unsubscribe@apereo.org.
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/d47843c7-3245-4367-8c7f-d457180c5221%40apereo.org.

Viacheslav Babanin

unread,
Apr 25, 2018, 2:43:46 AM4/25/18
to CAS Community

 Yes, and it releases attributes via saml with no issues. Only SLO doesn't work.


вторник, 24 апреля 2018 г., 15:16:32 UTC+2 пользователь Manfredo Hopp написал:

Viacheslav Babanin

unread,
Apr 25, 2018, 2:47:46 AM4/25/18
to CAS Community
This shouldn't matter since cas 4.1.9 sends same request and SAME client, placed in same directory on the same server handles it correctly.
From phpCAS.log

SAML REQUEST: <samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="LR-32-00RgstM5HOaqse3j9kIhNbUN1VfnSnhUzSb" Version="2.0" IssueInstant="2018-04-25T08:46:25Z"><saml:NameID xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">@NOT_USED@</saml:NameID><samlp:SessionIndex>ST-149-YAFlxnMQjDojiStFG4eN-cas.uek.krakow.pl</samlp:SessionIndex></samlp:LogoutRequest> [Client.php:1752]


вторник, 24 апреля 2018 г., 19:09:17 UTC+2 пользователь Manfredo Hopp написал:

Viacheslav Babanin

unread,
Apr 25, 2018, 3:20:32 AM4/25/18
to CAS Community
I have checked apache access.log on web server where client is placed and there is no POST requests on logout. 0 messages or requests completely. Thats while logging out with my cas 5.2.3
I have checked same log when i issue logout from cas 4.1.9 where SLO works on same client, and I can see POST request in access.log correctly.

вторник, 24 апреля 2018 г., 18:42:19 UTC+2 пользователь rbon написал:

Viacheslav Babanin

unread,
Apr 25, 2018, 6:02:14 AM4/25/18
to CAS Community
Thanks everybody for replies.
I have solved my problem.
I looked into tcpdump on CAS server to see what happens when I issue a logout, and I've seen that it sends logout request to some strange ip address on 443 port, which was blocked on this address.
Upon furter envestigation i figured out that it was a proxy problem and i opened /etc/profile.d/proxy.sh and changed 443 port to port which our proxy uses.


понедельник, 23 апреля 2018 г., 16:05:20 UTC+2 пользователь Viacheslav Babanin написал:
Reply all
Reply to author
Forward
0 new messages