Discourse-saml: SLO no cancela la sesión

Hola,

tenemos la siguiente configuración:
Discourse oficial 2.5.0 ([ 3f7658cc6e ]) con el plugin discourse-saml (commit 230a58b),
Keycloak (10.0.2) como Proveedor de Identidad (IdP).

Nuestro Proveedor de Identidad está configurado para usar la URL https://discourse.our-domain.xxx/auth/saml/slo como URL de Enlace POST del Servicio de Cierre de Sesión. Nuestro proceso de inicio de sesión funciona sin problemas. Al usar el botón de cierre de sesión en Discourse, también se cancela la sesión del IdP.

El problema ocurre cuando se utiliza la funcionalidad de cierre de sesión del IdP. Discourse no cancela la sesión. El foro recibe la solicitud, pero parece no manejarla correctamente. El usuario permanece conectado y obtenemos un error en el registro de Discourse.

El nombre de usuario para los siguientes registros es test.

Started POST "/auth/saml/slo" for 127.0.0.1 at 2020-07-09 18:29:33 +0000                                                                                                                            
OmniAuth::Strategies::SAML::ValidationError (SAML failed to process LogoutRequest)                                                                                                                  
/var/www/discourse/plugins/discourse-saml/gems/2.6.6/gems/omniauth-saml-1.9.0/lib/omniauth/strategies/saml.rb:189:in `handle_logout_request'

La condición if que lleva a la excepción es la siguiente (saml.rb):

if logout_request.is_valid? &&
     logout_request.name_id == session["saml_uid"]
código para salida de depuración
STDERR.puts '*************************************************************************'
STDERR.puts 'raw_request:'                                                             
STDERR.puts raw_request                                                                
STDERR.puts '*************************************************************************'
STDERR.puts 'logout_request.is_valid?'                                                 
STDERR.puts logout_request.is_valid?                                                   
STDERR.puts '*************************************************************************'
STDERR.puts 'logout_request.name_id'                                                   
STDERR.puts logout_request.name_id                                                     
STDERR.puts '*************************************************************************'
STDERR.puts 'session[saml_uid]'                                                        
STDERR.puts session["saml_uid"]                                                        
STDERR.puts '*************************************************************************'

Agregamos la salida de depuración en saml.rb (línea 181) y recibimos los siguientes valores:

*************************************************************************
raw_request:
solicitud cruda (decodificada con base64)
<?xml version="1.0"?>
<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Destination="https://discourse.test.our-domain.xxx/auth/saml/slo" ID="ID_ee6ef1f7-a269-443f-9942-1311b2c09636" IssueInstant="2020-07-09T19:20:27.882Z" Version="2.0">
  <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://ima.test.our-domain.xxx/auth/realms/master</saml:Issuer>
  <dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
    <dsig:SignedInfo>
      <dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
      <dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
      <dsig:Reference URI="#ID_ee6ef1f7-a269-443f-9942-1311b2c09636">
        <dsig:Transforms>
          <dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
          <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
        </dsig:Transforms>
        <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
        <dsig:DigestValue>nbeIwX97u+NNRf4KswI95oSmI2w=</dsig:DigestValue>
      </dsig:Reference>
    </dsig:SignedInfo>
    <dsig:SignatureValue>[...]</dsig:SignatureValue>
    <dsig:KeyInfo>
      <dsig:KeyName>[...]</dsig:KeyName>
      <dsig:X509Data>
        <dsig:X509Certificate>[...]</dsig:X509Certificate>
      </dsig:X509Data>
      <dsig:KeyValue>
        <dsig:RSAKeyValue>
          <dsig:Modulus>[...]</dsig:Modulus>
          <dsig:Exponent>AQAB</dsig:Exponent>
        </dsig:RSAKeyValue>
      </dsig:KeyValue>
    </dsig:KeyInfo>
  </dsig:Signature>
  <saml:NameID xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">test</saml:NameID>
  <samlp:SessionIndex>393fc3ab-6a18-4b8e-89a5-a005fc48f7cf::36a71dc0-22a0-4b72-be02-68639bedea06</samlp:SessionIndex>
</samlp:LogoutRequest>

*************************************************************************
logout_request.is_valid?           
true                                          
*************************************************************************
logout_request.name_id
test
*************************************************************************
session[saml_uid]
                                                                       
*************************************************************************

¿Puede alguien ayudarnos? No parece ser un problema de configuración.

Gracias de antemano.

Max

No estamos manejando el valor de sesión saml_uid en nuestro plugin. Este es gestionado por el propio gem omniauth-saml. Por lo tanto, no estoy seguro de por qué tienes un valor vacío en session["saml_uid"]. Es posible que debas reportar el problema en el gem de omniauth.

Además, ninguno de los clientes ha reportado ningún problema con SLO hasta ahora.

He identificado lo mismo:

  • Dos aplicaciones (Discourse y otra, llamémosla X) conectadas a Keycloak mediante SAML.
  • Cerrar sesión en Discourse. El usuario también queda desconectado en X y no puede hacer nada allí.
  • Cerrar sesión en X. La sesión en Keycloak desaparece, pero el usuario sigue conectado en Discourse.

Incluso una recarga de página en el navegador en Discourse no valida que la autenticación SAML haya desaparecido (= que el usuario haya cerrado sesión).

Esperaría que el usuario también se desconectara en Discourse.
¿Verifica Discourse la autenticación SAML en Keycloak?
¿Cuándo lo hace?

¿Sería posible validar si la sesión SAML sigue activa? Consulta la respuesta anterior @vinothkannans