jacekkow / keycloak-protocol-cas

CAS protocol provider for Keycloak
https://issues.jboss.org/browse/KEYCLOAK-1047
Apache License 2.0
96 stars 30 forks source link

Single log-out spec compliant, but not compatible with CAS libraries #57

Closed damisanet closed 2 years ago

damisanet commented 2 years ago

keycloak-protocol-cas transmits SLO requests in request body, which seems to match CAS protocol spec. However, official Apereo CAS client libraries are looking for logout requests in logoutRequest POST field...

phpCAS: https://github.com/apereo/phpCAS/blob/57fa31cdeaf99225c9c64b12e1cce21997e305e5/source/CAS/Client.php#L1908-L1911 https://github.com/apereo/phpCAS/blob/57fa31cdeaf99225c9c64b12e1cce21997e305e5/source/CAS/Client.php#L1939

java-cas-client: https://github.com/apereo/java-cas-client/blob/0be716e1ac70c596e284bd502d8c34d89d7e58e0/cas-client-core/src/main/java/org/apereo/cas/client/configuration/ConfigurationKeys.java#L43 https://github.com/apereo/java-cas-client/blob/0be716e1ac70c596e284bd502d8c34d89d7e58e0/cas-client-core/src/main/java/org/apereo/cas/client/session/SingleSignOutHandler.java#L300-L304 https://github.com/apereo/java-cas-client/blob/0be716e1ac70c596e284bd502d8c34d89d7e58e0/cas-client-core/src/main/java/org/apereo/cas/client/session/SingleSignOutHandler.java#L221 https://github.com/apereo/java-cas-client/blob/0be716e1ac70c596e284bd502d8c34d89d7e58e0/cas-client-core/src/main/java/org/apereo/cas/client/session/SingleSignOutHandler.java#L226

dotnet-cas-client: https://github.com/apereo/dotnet-cas-client/blob/2677b8d182af40d490644e08d194ce811f3e3795/DotNetCasClient/Utils/RequestEvaluator.cs#L274 https://github.com/apereo/dotnet-cas-client/blob/2677b8d182af40d490644e08d194ce811f3e3795/DotNetCasClient/CasAuthentication.cs#L746

It seems that other third-party libraries (e.g. django-cas-ng, rubycas-client-rails) follow official libraries behavior instead of adhering to protocol specs. I am unable to find any justification why logout requests are sent using POST field and why on earth it is called logoutRequest (it doesn't even mimic SAML, as real SAML logout requests use SAMLRequest POST field).

Other CAS server implementation had the same problem: https://github.com/jbittel/django-mama-cas/issues/27

While I believe it is stupid of Apereo not to follow their own specs, non-compliant single log-out method became de facto standard and keycloak-protocol-cas should probably also switch to sending logout requests using logoutRequest POST field. What do you think?

I'm able to provide patch changing plugin behavior to match "official" CAS server implementation.

10101010101010001 commented 2 years ago

It seems that other third-party libraries (e.g. django-cas-ng, rubycas-client-rails) follow official libraries behavior instead of adhering to protocol specs. I am unable to find any justification why logout requests are sent using POST field and why on earth it is called logoutRequest (it doesn't even mimic SAML, as real SAML logout requests use SAMLRequest POST field).

I've been working with CAS lately and I can tell you that CAS doesn't manage sessions, that's done by the application. So if you logout of CAS but don't logout of the application(s) then you didn't really logout. Even worse when you have several services all requiring login, how do you keep track of which services have been logged into so you can send all of them the logout post request. soulwing/cas-extension also suffers from this issue.

I think it's necessary to patch, I am looking for something that works with several hundreds of webapps all requiring authentication. I'm using container managed security, requires security-constraints with role-names in web.xml.

damisanet commented 2 years ago

I've been working with CAS lately and I can tell you that CAS doesn't manage sessions, that's done by the application. So if you logout of CAS but don't logout of the application(s) then you didn't really logout.

Both Apereo CAS and keycloak-protocol-cas are definitely capable of tracking user sessions and sending backchannel logout requests on CAS logout. In our org we rely on this behavior for a long time - this issue was created because we observed that while logout from Keycloak triggers HTTP POST requests from CAS server to CAS clients just like Apereo CAS did, it doesn't result in logout from apps (and changes described in my first comment are enough to fix this).

I am looking for something that works with several hundreds of webapps all requiring authentication.

To be honest, we use keycloak-protocol-cas only because we have some apps tied to CAS protocol (with no support for other protocols or local auth - these apps are even bundled with pre-configured Apereo CAS instance...). All of our in-house developed/modified apps are using OpenID Connect (also its Backchannel Logout feature) exclusively, which works great with Keycloak.

jacekkow commented 2 years ago

I'm able to provide patch changing plugin behavior to match "official" CAS server implementation.

@damisanet - create a pull request, please. But don't bring CASia back from the dead ;)

damisanet commented 2 years ago

@damisanet - create a pull request, please. But don't bring CASia back from the dead ;)

Took me a while, but here it is - #62. Yeah, Casia is definitely not coming back ;)