Discourse-saml: SLO はセッションをキャンセルしません

こんにちは、

以下の構成になっています:
公式 Discourse 2.5.0 ([ 3f7658cc6e ]) に discourse-saml プラグイン(コミット 230a58b)を適用
Keycloak (10.0.2) をアイデンティティプロバイダーとして使用

アイデンティティプロバイダーでは、ログアウトサービス POST バインディング URL として https://discourse.our-domain.xxx/auth/saml/slo を設定しています。ログインプロセスは問題なく動作しており、Discourse 内のログアウトボタンを使用すると、IdP のセッションも正常に終了します。

問題は、IdP のログアウト機能を使用した際に発生します。Discourse はセッションをキャンセルしません。フォーラム側ではリクエストは受信されていますが、適切に処理されていないようです。ユーザーはログインしたままの状態が続き、Discourse のログにエラーが記録されます。

以下のログのユーザー名は 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'

例外に至る if 条件は以下の通りです(saml.rb):

if logout_request.is_valid? &&
     logout_request.name_id == session["saml_uid"]
デバッグ出力用のコード
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 '*************************************************************************'

saml.rb の 181 行目に上記のデバッグ出力を追加し、以下の値を取得しました:

*************************************************************************
raw_request:
raw request (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]
                                                                       
*************************************************************************

どなたかお手伝いいただけますでしょうか?設定の問題ではないように思われます。

よろしくお願いいたします

Max

当社のプラグインでは saml_uid セッション値の処理は行っておりません。これは omniauth-saml ギム自体が処理するものです。そのため、session["saml_uid"] が空の値になっている理由については確信が持てません。omniauth ギムに対して issue を報告する必要があるかもしれません。

また、SLO に関する問題は現在までに顧客から報告されていません。

同じ現象を確認しています:

  • Keycloak と SAML で接続された 2 つのアプリケーション(Discourse と、仮に X と呼びます)
  • Discourse でログアウトすると、X でもユーザーがログアウトされ、何もできなくなる
  • X でログアウトすると、Keycloak のセッションは消失するが、Discourse 側ではユーザーが引き続きログインしたままになる

Discourse のブラウザページを再読み込みしても、SAML 認証が失われている(=ユーザーがログアウトしている)ことが検証されません。

Discourse 側でもユーザーがログアウトされることを期待しています。
Discourse は Keycloak の SAML 認証を確認するのでしょうか?
また、それはいつ行われるのでしょうか?

SAML セッションがまだ有効かどうかを確認することは可能でしょうか?上記の回答を参照してください @vinothkannans