第3章 SAML を使用したアプリケーションとサービスのセキュア化


本セクションでは、Red Hat Single Sign-On クライアントアダプターまたは汎用 SAML プロバイダーライブラリーを使用して SAML でアプリケーションおよびサービスのセキュリティーを保護する方法を説明します。

3.1. Java アダプター

Red Hat Single Sign-On には、Java アプリケーションのさまざまなアダプターがあります。正しいアダプターの選択は、ターゲットプラットフォームによって異なります。

3.1.1. 汎用アダプターの設定

Red Hat Single Sign-On がサポートする各 SAML クライアントアダプターは、単純な XML テキストファイルで設定できます。これは次のようになります。

<keycloak-saml-adapter xmlns="urn:keycloak:saml:adapter"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:schemaLocation="urn:keycloak:saml:adapter https://www.keycloak.org/schema/keycloak_saml_adapter_1_10.xsd">
    <SP entityID="http://localhost:8081/sales-post-sig/"
        sslPolicy="EXTERNAL"
        nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
        logoutPage="/logout.jsp"
        forceAuthentication="false"
        isPassive="false"
        turnOffChangeSessionIdOnLogin="false"
        autodetectBearerOnly="false">
        <Keys>
            <Key signing="true" >
                <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
                    <PrivateKey alias="http://localhost:8080/sales-post-sig/" password="test123"/>
                    <Certificate alias="http://localhost:8080/sales-post-sig/"/>
                </KeyStore>
            </Key>
        </Keys>
        <PrincipalNameMapping policy="FROM_NAME_ID"/>
        <RoleIdentifiers>
            <Attribute name="Role"/>
        </RoleIdentifiers>
        <RoleMappingsProvider id="properties-based-role-mapper">
            <Property name="properties.resource.location" value="/WEB-INF/role-mappings.properties"/>
        </RoleMappingsProvider>
        <IDP entityID="idp"
             signaturesRequired="true">
        <SingleSignOnService requestBinding="POST"
                             bindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
                    />

            <SingleLogoutService
                    requestBinding="POST"
                    responseBinding="POST"
                    postBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
                    redirectBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
                    />
            <Keys>
                <Key signing="true">
                    <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
                        <Certificate alias="demo"/>
                    </KeyStore>
                </Key>
            </Keys>
        </IDP>
     </SP>
</keycloak-saml-adapter>

これらの設定スイッチの一部はアダプター固有で、一部の設定がすべてのアダプターで共通となる場合があります。Java アダプターでは、システムプロパティーの置き換えとして ${…​} エンクロージャーを使用できます。たとえば ${jboss.server.config.dir} になります。

3.1.1.1. SP 要素

SP 要素属性の説明は次のとおりです。

<SP entityID="sp"
    sslPolicy="ssl"
    nameIDPolicyFormat="format"
    forceAuthentication="true"
    isPassive="false"
    keepDOMAssertion="true"
    autodetectBearerOnly="false">
...
</SP>
entityID
これは、このクライアントの ID です。IdP では、クライアントが通信しているユーザーを判別するためにこの値が必要です。この設定は 必須 です。
sslPolicy
これは、アダプターが強制する SSL ポリシーです。有効な値は ALLEXTERNAL、および NONE です。ALL の場合、すべてのリクエストは HTTPS 経由で受信する必要があります。EXTERNAL の場合、非プライベート IP アドレスのみが HTTPS 経由で有線を通過する必要があります。NONE の場合、HTTPS 経由のリクエストはありません。この設定は 任意 です。デフォルト値は EXTERNAL です。
nameIDPolicyFormat
SAML クライアントは、特定の NameID Subject 形式を要求できます。特定の形式が必要な場合は、この値を入力します。標準の SAML 形式の識別子である urn:oasis:names:tc:SAML:2.0:nameid-format:transient ある必要があります。この設定は 任意 です。デフォルトでは、特別な形式は要求されません。
forceAuthentication
SAML クライアントは、ユーザーが IdP にすでにログインしていても、再認証することをリクエストできます。有効にするには、これを true に設定します。この設定は 任意 です。デフォルト値は false です。
isPassive
SAML クライアントは、IdP にログインしていない場合でも、ユーザーの認証が要求されないように要求できます。必要に応じてこれを true に設定します。forceAuthentication は逆の設定なので、一緒に使用しないでください。この設定は 任意 です。デフォルト値は false です。
turnOffChangeSessionIdOnLogin
セッション ID は、一部のプラットフォームで正常にログインしてセキュリティー攻撃ベクトルをプラグインするためにデフォルトで変更されます。これを無効にするには、これを true に変更します。オフにしないことが推奨されます。デフォルト値は false です。
autodetectBearerOnly
アプリケーションが Web アプリケーションと Web サービス (例: SOAP または REST) の両方に対応する場合は、true に設定する必要があります。Web アプリケーションの認証されていないユーザーを Red Hat Single Sign-On ログインページにリダイレクトできますが、認証されていない SOAP または REST クライアントに HTTP 401 ステータスコードを送信することができます。ログインページへのリダイレクトは理解できません。Red Hat Single Sign-On は、X-Requested-WithSOAPAction、または Accept などの一般的なヘッダーに基づいて SOAP クライアントまたは REST クライアントを自動検出します。デフォルト値は false です。
logoutPage
これにより、ログアウト後に表示するページが設定されます。ページが http://web.example.com/logout.html などの完全な URL の場合、ユーザーは HTTP 302 ステータスコードを使用してログアウト後にそのページにリダイレクトされます。スキーム部分のないリンク (例: /logout.jsp) が指定されると、web.xml の security-constraint 宣言に従って保護領域に存在するかどうかに関係なく、ログアウトの後にページが表示され、ページがデプロイメントコンテキストルートとの関連で解決されます。
keepDOMAssertion
この属性は true に設定して、要求に関連付けられた SamlPrincipal 内の元の形式でアダプターストアにアサーションの DOM 表現を設定します。アサーションドキュメントは、プリンシパル内の getAssertionDocument メソッドを使用して取得できます。これは、署名済みアサーションの再生時に特に便利です。返されるドキュメントは、Red Hat Single Sign-On サーバーが受信した SAML 応答を解析して生成されたドキュメントです。この設定は 任意 で、デフォルト値は false です (ドキュメントはプリンシパルに保存されません)。

3.1.1.2. サービスプロバイダーキーおよびキー要素

IdP で、クライアントアプリケーション (または SP) がすべての要求に署名するか、IdP がアサーションを暗号化する場合は、これを実行するために使用するキーを定義する必要があります。クライアント署名のドキュメントでは、ドキュメントの署名に使用される秘密鍵、および公開鍵または証明書の両方を定義する必要があります。暗号化の場合は、復号に使用する秘密鍵のみを定義する必要があります。

キーを記述する方法は 2 つあります。キーは Java KeyStore 内に格納することも、PEM 形式の keycloak-saml.xml にキーを直接コピー/貼り付けることもできます。

        <Keys>
            <Key signing="true" >
               ...
            </Key>
        </Keys>

Key 要素には、2 つの任意の属性の signing および encryption があります。true に設定すると、これらはアダプターにキーの使用目的を通知します。両方の属性が true に設定されていると、キーはドキュメントの署名と暗号化されたアサーションの復号の両方に使用されます。少なくとも 1 つの属性を true に設定する必要があります。

3.1.1.2.1. キーストア要素

Key 要素内で、Java Keystore から鍵と証明書を読み込みます。これは KeyStore 要素内で宣言されます。

        <Keys>
            <Key signing="true" >
                <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
                    <PrivateKey alias="myPrivate" password="test123"/>
                    <Certificate alias="myCertAlias"/>
                </KeyStore>
            </Key>
        </Keys>

以下は、KeyStore 要素で定義されている XML 設定属性です。

file
キーストアへのファイルパス。このオプションは 任意 です。file または resource 属性を設定する必要があります。
resource
KeyStore への WAR リソースパス。これは、ServletContext.getResourceAsStream() へのメソッド呼び出しで使用されるパスです。このオプションは 任意 です。file または resource 属性を設定する必要があります。
password
KeyStore のパスワード。このオプションは 必須 です。

SP がドキュメントの署名に使用するキーを定義する場合は、Java KeyStore 内の秘密鍵および証明書への参照も指定する必要があります。上記の例の PrivateKey および Certificate 要素は、キーストア内のキーまたは証明書を参照する エイリアス を定義します。キーストアには、秘密鍵にアクセスするために追加のパスワードが必要です。PrivateKey 要素で、password 属性内にこのパスワードを定義する必要があります。

3.1.1.2.2. キーの PEMS

Key 要素内で、PrivateKeyPemPublicKeyPem および CertificatePem のサブ要素を使用して、キーと証明書を直接宣言します。これらの要素に含まれる値は PEM キー形式に準拠する必要があります。通常、openssl または同様のコマンドラインツールを使用してキーを生成する場合は、このオプションを使用します。

<Keys>
   <Key signing="true">
      <PrivateKeyPem>
         2341251234AB31234==231BB998311222423522334
      </PrivateKeyPem>
      <CertificatePem>
         211111341251234AB31234==231BB998311222423522334
      </CertificatePem>
   </Key>
</Keys>

3.1.1.3. SP PrincipalNameMapping 要素

この要素は任意です。HttpServletRequest.getUserPrincipal() などのメソッドから取得する Java Principal オブジェクトを作成する場合は、Principal.getName() メソッドによって返される名前を定義できます。

<SP ...>
  <PrincipalNameMapping policy="FROM_NAME_ID"/>
</SP>

<SP ...>
  <PrincipalNameMapping policy="FROM_ATTRIBUTE" attribute="email" />
</SP>

policy 属性は、この値に設定するために使用されるポリシーを定義します。この属性に使用できる値は次のとおりです。

FROM_NAME_ID
このポリシーは SAML サブジェクト値を使用するだけです。これはデフォルト設定です。
FROM_ATTRIBUTE
これにより、サーバーから受信した SAML アサーションで宣言された属性のいずれかから値をプルします。XML 属性 attribute 内で使用する SAML の assertion 属性の名前を指定する必要があります。

3.1.1.4. RoleIdentifiers 要素

RoleIdentifiers 要素は、ユーザーから受け取ったアサーション内の SAML 属性を、ユーザーの Jakarta EE Security Context 内のロール識別子として使用する必要があります。

<RoleIdentifiers>
     <Attribute name="Role"/>
     <Attribute name="member"/>
     <Attribute name="memberOf"/>
</RoleIdentifiers>

デフォルトでは、Role 属性値は Jakarta EE ロールに変換されます。一部の IdP は、member または memberOf 属性アサーションを使用してロールを送信します。1 つ以上の Attribute 要素を定義して、ロールに変換する必要のある SAML 属性を指定できます。

3.1.1.5. RoleMappingsProvider 要素

RoleMappingsProvider は、SAML アダプターによって使用される SPI 実装 org.keycloak.adapters.saml.RoleMappingsProvider の ID および設定を許可するオプションの要素です。

Red Hat Single Sign-On が IDP として使用されると、ビルドされたロールマッパーを使用して、ロールを SAML アサーションに追加する前にマッピングできます。ただし、SAML アダプターを使用して、SAML リクエストをサードパーティーの IDP に送信するびに使用できます。この場合は、SP の必要に応じてアサーションからデプロイメントされたロールを異なるロールセットにマッピングすることが必要になる場合があります。RoleMappingsProvider SPI は、必要なマッピングを実行するのに使用できるプラグ可能なロールマッパーの設定を可能にします。

プロバイダーの設定は以下のようになります。

...
<RoleIdentifiers>
    ...
</RoleIdentifiers>
<RoleMappingsProvider id="properties-based-role-mapper">
    <Property name="properties.resource.location" value="/WEB-INF/role-mappings.properties"/>
</RoleMappingsProvider>
<IDP>
    ...
</IDP>

id 属性は、使用するインストール済みプロバイダーを特定します。Property サブ要素は複数回使用してプロバイダーの設定プロパティーを指定できます。

3.1.1.5.1. プロパティーベースのロールマッピングプロバイダー

Red Hat Single Sign-On には、properties ファイルを使用してロールマッピングを実行する RoleMappingsProvider 実装が含まれています。このプロバイダーは id properties-based-role-mapper によって識別され、org.keycloak.adapters.saml.PropertiesBasedRoleMapper クラスによって実装されます。

このプロバイダーは、使用される properties ファイルの場所を指定するために使用できる 2 つの設定プロパティーに依存します。最初に、設定値を使用して、ファイルシステムで properties ファイルを見つけることで、properties.file.location プロパティーが指定されているかどうかを確認します。設定したファイルが見つからない場合、プロバイダーは RuntimeException を出力します。以下のスニペットは、properties.file.configuration オプションを使用して、ファイルシステムの /opt/mappers/ ディレクトリーから roles.properties ファイルを読み込むプロバイダーの例を示しています。

    <RoleMappingsProvider id="properties-based-role-mapper">
        <Property name="properties.file.location" value="/opt/mappers/roles.properties"/>
    </RoleMappingsProvider>

properties.file.location 設定が設定されていない場合、プロバイダーは properties.resource.location プロパティーをチェックし、設定した値を使用して WAR リソースから properties ファイルを読み込みます。この設定プロパティーがない場合、プロバイダーはデフォルトで /WEB-INF/role-mappings.properties からファイルを読み込もうとします。リソースからファイルを読み込めない場合、プロバイダーは RuntimeException を出力します。以下のスニペットは、properties.resource.location を使用してアプリケーションの /WEB-INF/conf/ ディレクトリーから roles.properties ファイルを読み込むプロバイダーの例を示しています。

    <RoleMappingsProvider id="properties-based-role-mapper">
        <Property name="properties.resource.location" value="/WEB-INF/conf/roles.properties"/>
    </RoleMappingsProvider>

properties ファイルには、ロールとプリンシパルの両方をキーとして含めることができ、0 つ以上のロールを値としてコンマで区切ります。呼び出されると、実装はアサーションから抽出したロールのセットを繰り返し処理し、各ロールについて、マッピングが存在するかどうかを確認します。ロールが空ロールにマップする場合、これは破棄されます。1 つ以上の異なるロールのセットにマップすると、これらのロールは結果セットに設定されます。ロールのマッピングが見つからない場合は、結果セットに組み込まれます。

ロールの処理後、アサーションから抽出したプリンシパルにエントリーの properties ファイルが含まれるかどうかを確認します。プリンシパルのマッピングが存在する場合は、値としてリスト表示されるすべてのロールが結果セットに追加されます。これにより、追加のロールをプリンシパルに割り当てることができます。

たとえば、プロバイダーが以下のプロパティーファイルで設定されていると仮定します。

roleA=roleX,roleY
roleB=

kc_user=roleZ

プリンシパル kc_user が、roleAroleB、および roleC があるアサーションから抽出されると、プリンシパルに割り当てられたロールの最終セットは roleCroleXroleY、および roleZ になります。なぜなら roleAroleX および roleY にマッピングされ、roleB が空のロールにマッピングされて破棄され、roleC がそのまま使用され、追加ロールが kc_user プリンシパル (roleZ) に追加されるためです。

注記: マッピングのロール名にスペースを使用するには、Unicode の空白文字を使用してください。たとえば、受信したロール A は以下のように表示されます。

role\u0020A=roleX,roleY
3.1.1.5.2. 独自のロールマッピングプロバイダーの追加

カスタムロールマッピングプロバイダーを追加するには、単に org.keycloak.adapters.saml.RoleMappingsProvider SPI を実装する必要があります。詳細は、Server Developer GuideSAML Role Mappings SPI セクションを参照してください。

3.1.1.6. IDP 要素

IDP 要素のすべては、SP が通信しているアイデンティティープロバイダー (認証トークン) の設定を記述します。

<IDP entityID="idp"
     signaturesRequired="true"
     signatureAlgorithm="RSA_SHA1"
     signatureCanonicalizationMethod="http://www.w3.org/2001/10/xml-exc-c14n#">
...
</IDP>

以下は、IDP 要素宣言内で指定できる属性設定オプションです。

entityID
これは IDP の発行者 ID です。この設定は 必須 です。
signaturesRequired
true に設定すると、クライアントアダプターは IDP に送信するすべてのドキュメントに署名します。また、クライアントは IDP が送信されたドキュメントに署名されることを想定します。このスイッチは、すべての要求および応答タイプのデフォルトを設定しますが、後でこのタイプを詳細に制御できることがわかります。この設定は 任意 で、デフォルトは false に設定されます。
signatureAlgorithm
これは、IDP により署名されたドキュメントで使用することが必要な署名アルゴリズムです。使用できる値は、RSA_SHA1RSA_SHA256RSA_SHA512、および DSA_SHA1 です。この設定は 任意 で、デフォルト値は RSA_SHA256 です。
signatureCanonicalizationMethod
これは、IDP により署名されたドキュメントで使用することが必要な署名の正規化方法です。この設定は 任意 です。デフォルト値は http://www.w3.org/2001/10/xml-exc-c14n# で、大抵の IDP に適しています。
metadataUrl
IDP メタデータの取得に使用される URL。現在、これは署名キーと暗号化キーを定期的に取得するためにのみ使用され、SP 側で手動で変更することなく IDP でこれらのキーを循環させることができます。

3.1.1.7. IDP AllowedClockSkew サブ要素

AllowedClockSkew オプションの sub 要素は、IDP と SP の間で許可されるクロックの skew を定義します。デフォルト値は 0 です。

<AllowedClockSkew unit="MILLISECONDS">3500</AllowedClockSkew>
unit
この要素の値に割り当てられた時間単位を定義することができます。使用できる値は MICROSECONDS、MILLISECONDS、MINUTES、NANOSECONDS、および SECONDS です。これは 任意 です。デフォルト値は SECONDS です。

3.1.1.8. IDP SingleSignOnService サブ要素

サブ要素 SingleSignOnService は、IDP のログイン SAML エンドポイントを定義します。クライアントアダプターは、ログイン時にこの要素内の設定を介してフォーマットされた IDP に要求を送信します。

<SingleSignOnService signRequest="true"
                     validateResponseSignature="true"
                     requestBinding="post"
                     bindingUrl="url"/>

この要素で定義できる config 属性を以下に示します。

signRequest
クライアントは認証要求に署名する必要がありますか ?この設定は 任意 です。デフォルトは、任意の IDP の signaturesRequired 要素の値に設定されます。
validateResponseSignature
クライアントは、IDP が auhtn 要求から返送されたアサーション応答ドキュメントに署名することを期待する必要がありますか ?この設定は 任意 です。デフォルトは、任意の IDP の signaturesRequired 要素の値に設定されます。
requestBinding
これは IDP との通信に使用される SAML バインディングタイプです。この設定は 任意 です。デフォルト値は POST ですが、REDIRECT に設定することもできます。
responseBinding
SAML を使用すると、クライアントは、認証応答で使用するバインディングタイプを要求できます。値は POST または REDIRECT です。この設定は 任意 です。デフォルトでは、クライアントは応答用に特定のバインディングタイプを要求しません。
assertionConsumerServiceUrl
IDP ログインサービスが応答を送信する必要がある Assertion Consumer Service (ACS) の URL。この設定は 任意 です。デフォルトでは、IdP の設定に依存するため、これは未設定です。設定した場合は、/saml (例: http://sp.domain.com/my/endpoint/for/saml) で終了する必要があります。このプロパティーの値は SAML AuthnRequest メッセージの AssertionConsumerServiceURL 属性で送信されます。通常、このプロパティーには responseBinding 属性が伴います。
bindingUrl
これは、クライアントが要求を送信する IDP ログインサービスの URL です。この設定は 必須 です。

3.1.1.9. IDP SingleLogoutService サブ要素

サブ要素 SingleLogoutService は、IDP のログアウト SAML エンドポイントを定義します。クライアントアダプターは、ログアウト時にこの要素内の設定を介してフォーマットされた IDP に要求を送信します。

<SingleLogoutService validateRequestSignature="true"
                     validateResponseSignature="true"
                     signRequest="true"
                     signResponse="true"
                     requestBinding="redirect"
                     responseBinding="post"
                     postBindingUrl="posturl"
                     redirectBindingUrl="redirecturl">
signRequest
クライアントは、IDP に対して行うログアウト要求に署名する必要がありますか ?この設定は 任意 です。デフォルトは、任意の IDP の signaturesRequired 要素の値に設定されます。
signResponse
クライアントが、IDP 要求に送信するログアウト応答に署名する必要があるかどうか。この設定は 任意 です。デフォルトは、任意の IDP の signaturesRequired 要素の値に設定されます。
validateRequestSignature
クライアントが、IDP からの署名済みログアウト要求ドキュメントを期待する必要があるかどうか。この設定は 任意 です。デフォルトは、任意の IDP の signaturesRequired 要素の値に設定されます。
validateResponseSignature
クライアントが、IDP からの署名済みログアウト応答ドキュメントを期待する必要があるか。この設定は 任意 です。デフォルトは、任意の IDP の signaturesRequired 要素の値に設定されます。
requestBinding
これは、IDP への SAML 要求の通信に使用される SAML バインディングタイプです。この設定は 任意 です。デフォルト値は POST ですが、REDIRECT に設定することもできます。
responseBinding
これは、IDP への SAML 応答の通信に使用される SAML バインディングタイプです。値は POST または REDIRECT です。この設定は 任意 です。デフォルト値は POST ですが、REDIRECT に設定することもできます。
postBindingUrl
これは、POST バインディングの使用時に IDP のログアウトサービスの URL です。この設定は、POST バインディングを使用する場合に 必須 になります。
redirectBindingUrl
これは、REDIRECT バインディングの使用時に IDP のログアウトサービスの URL です。この設定は、REDIRECT バインディングを使用する場合に 必須 になります。

3.1.1.10. IDP キーサブ要素

IDP のキーサブ要素は、IDP によって署名されたドキュメントの検証に使用する証明書またはパブリックキーの定義にのみ使用されます。これは、SP の Keys 要素 と同じ方法で定義されます。ただし、証明書または公開鍵参照を定義するだけで十分です。IDP と SP の両方が Red Hat Single Sign-On サーバーおよびアダプターによって実現される場合、署名の検証にキーを指定する必要はありません。以下を参照してください。

SP と IDP の両方が Red Hat Single Sign-On によって実装されている場合、公開された証明書から IDP 署名検証用の公開鍵を自動的に取得するように SP を設定することができます。これは、キーサブ要素の署名検証キーの宣言をすべて削除することによって行われます。キーサブ要素が空のままになる場合は、完全に省略できます。次に、キーは SP により SAML 記述子から自動的に取得されます。これは、IDP SingleSignOnService サブ要素 で指定された SAML エンドポイント URL から派生します。SAML 記述子取得に使用される HTTP クライアントの設定は、通常、追加設定は必要ありませんが、IDP HttpClient サブ要素 で設定することもできます。

署名の検証に複数のキーを指定することもできます。これは、signing 属性が true に設定されている Keys サブ要素内で複数の Key 要素を宣言することによって行われます。これは、IDP 署名鍵がローテートされる場合などに便利です。通常、新しい SAML プロトコルメッセージとアサーションが新しいキーで署名される際に移行期間がありますが、以前のキーで署名されたものは引き続き受け入れる必要があります。

署名検証用のキーの自動取得および追加の静的署名検証キーの定義の両方を行うように Red Hat Single Sign-On を設定することはできません。

       <IDP entityID="idp">
            ...
            <Keys>
                <Key signing="true">
                    <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
                        <Certificate alias="demo"/>
                    </KeyStore>
                </Key>
            </Keys>
        </IDP>

3.1.1.11. IDP HttpClient サブ要素

HttpClient オプションのサブ要素は、enabled の場合に、IDP の SAML 記述子で IDP 署名検証用の公開鍵を含む証明書を自動的に取得するために使用される HTTP クライアントのプロパティーを定義します。

<HttpClient connectionPoolSize="10"
            disableTrustManager="false"
            allowAnyHostname="false"
            clientKeystore="classpath:keystore.jks"
            clientKeystorePassword="pwd"
            truststore="classpath:truststore.jks"
            truststorePassword="pwd"
            proxyUrl="http://proxy/"
            socketTimeout="5000"
            connectionTimeout="6000"
            connectionTtl="500" />
connectionPoolSize
この設定オプションでは、Red Hat Single Sign-On サーバーへプールする接続の数を定義します。これは 任意 です。デフォルト値は 10 です。
disableTrustManager
Red Hat Single Sign-On サーバーに HTTPS が必要で、この設定オプションが true に設定されている場合は、トラストストアを指定する必要はありません。この設定は開発時のみ使用してください。これは SSL 証明書の検証を無効にするため、実稼働環境では 使用しないで ください。これは 任意 です。デフォルト値は false です。
allowAnyHostname
Red Hat Single Sign-On サーバーに HTTPS が必要で、この設定オプションが true に設定されている場合、Red Hat Single Sign-On サーバーの証明書はトラストストア経由で検証されますが、ホスト名の検証は行われません。この設定は開発時のみ使用してください。これは SSL 証明書の検証を一部無効にするため、実稼働環境では 使用しないで ください。この設定は、テスト環境で役に立ちます。これは 任意 です。デフォルト値は false です。
truststore
値は、トラストストアファイルへのファイルパスです。classpath: でパスを接頭辞にすると、代わりにデプロイメントのクラスパスからトラストストアが取得されます。Red Hat Single Sign-On サーバーへの送信 HTTPS 通信に使用されます。HTTPS 要求を実行するクライアントでは、通信先のサーバーのホストを確認する方法が必要です。これは、トラストストアが行なうことです。キーストアには、1 つ以上の信頼できるホスト証明書または認証局が含まれます。Red Hat Single Sign-On サーバーの SSL キーストアの公開証明書を抽出して、このトラストストアを作成できます。これは、disableTrustManagertrue でない限り 必須 になります。
truststorePassword
トラストストアのパスワード。これは、トラストストア が設定され、トラストストアにパスワードが必要な場合は 必須 になります。
clientKeystore
これはキーストアファイルに対するファイルパスです。このキーストアには、アダプターが Red Hat Single Sign-On サーバーに対して HTTPS を要求する際に双方向 SSL のクライアント証明書が含まれます。これは 任意 です。
clientKeystorePassword
クライアントキーストアおよびクライアントの鍵のパスワード。これは、clientKeystore が設定されている場合は REQUIRED になります。
proxyUrl
HTTP 接続に使用する HTTP プロキシーの URL。これは 任意 です。
socketTimeout
接続の確立後にデータを待つソケットのタイムアウト (ミリ秒単位)。2 つのデータパケット間の最長の非アクティブ時間。タイムアウト値 0 は無限のタイムアウトとして解釈されます。負の値は未定義として解釈されます (該当する場合はシステムのデフォルト)。デフォルト値は -1 です。これは 任意 です。
connectionTimeout
リモートホストとの接続を確立するためのタイムアウト (ミリ秒単位)。タイムアウト値 0 は無限のタイムアウトとして解釈されます。負の値は未定義として解釈されます (該当する場合はシステムのデフォルト)。デフォルト値は -1 です。これは 任意 です。
connectionTtl
クライアント向けの接続 Time to Live (TTL) (ミリ秒単位)。ゼロ以下の値は、無限の値として解釈されます。デフォルト値は -1 です。これは 任意 です。

3.1.2. JBoss EAP アダプター

JBoss EAP にデプロイされた WAR アプリケーションのセキュリティーを保護できるようにするには、Red Hat Single Sign-On アダプターサブシステムをインストールおよび設定する必要があります。

次に、WAR で keycloak 設定ファイル /WEB-INF/keycloak-saml.xml を指定し、auth-method を web.xml 内の Keycloak-SAML に変更します。

ZIP ファイルまたは RPM を使用してアダプターをインストールします。

3.1.3. ZIP ファイルからのアダプターのインストール

各アダプターは、Red Hat Single Sign-On のダウンロードサイトの個別ダウンロードです。

手順

  1. Downloads サイトからアプリケーションサーバーに適用されるアダプターをインストールします。

    • JBoss EAP 7.x にインストールします。

      $ cd $EAP_HOME
      $ unzip rh-sso-saml-eap7-adapter.zip
    • JBoss EAP 6.x にインストールします。

      $ cd $EAP_HOME
      $ unzip rh-sso-saml-eap6-adapter.zip

      これらの ZIP ファイルは、JBoss EAP ディストリビューション内に JBoss EAP SAML アダプターに固有の新しい JBoss モジュールを作成します。

  2. CLI スクリプトを使用して、アプリケーションサーバーのサーバー設定 (domain.xml または standalone.xml) 内で Red Hat Single Sign-On SAML サブシステムを有効にします。

    サーバーを起動し、アプリケーションサーバーに適用するスクリプトを実行します。

    • JBoss EAP 7.1 以降の場合は、このコマンドを使用します。

      $ cd $JBOSS_HOME
      $ ./bin/jboss-cli.sh -c --file=bin/adapter-elytron-install-saml.cli
      注記

      7.4.CP7 および 7.4.CP8 以降、EAP はそれぞれ OpenJDK 17 および Oracle JDK 17 をサポート しています。新しい Java バージョンでは elytron バリアントが必須になるため、JDK 17 でレガシーアダプターを使用しないでください。また、アダプターの CLI ファイルを実行した後、EAP が提供する enable-elytron-se17.cli スクリプトを実行します。elytron アダプターを設定し、互換性のない EAP サブシステムを削除するには、両方のスクリプトが必要です。詳細は Security Configuration Changes の記事を参照してください。

    • JBoss EAP 7.0 および EAP 6.4 の場合は、このコマンドを使用します。

      $ cd $JBOSS_HOME
      $ ./bin/jboss-cli.sh -c --file=bin/adapter-install-saml.cli
      注記

      JBoss EAP 7.1 以上でも従来の非 Elytron アダプターを使用できます。つまり、これらのバージョンでも adapter-install-saml.cli を使用できます。ただし、新しい Elytron アダプターを使用することが推奨されます。

      スクリプトは、以下に説明するように、拡張機能、サブシステム、およびオプションの security-domain を追加します。

<server xmlns="urn:jboss:domain:1.4">

    <extensions>
        <extension module="org.keycloak.keycloak-saml-adapter-subsystem"/>
          ...
    </extensions>

    <profile>
        <subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1"/>
         ...
    </profile>

セキュアな Web 層で作成されたセキュリティーコンテキストを、呼び出している EJB (他の EE コンポーネント) に伝播する必要がある場合には、keycloak セキュリティードメインを EJB およびその他のコンポーネントと併用する必要があります。それ以外の場合、この設定は任意です。

<server xmlns="urn:jboss:domain:1.4">
 <subsystem xmlns="urn:jboss:domain:security:1.2">
    <security-domains>
...
      <security-domain name="keycloak">
         <authentication>
           <login-module code="org.keycloak.adapters.jboss.KeycloakLoginModule"
                         flag="required"/>
          </authentication>
      </security-domain>
    </security-domains>

セキュリティーコンテキストは EJB 階層に自動的に伝播されます。

3.1.3.1. JBoss SSO

JBoss EAP は、同じ JBoss EAP インスタンスにデプロイされた web アプリケーションに対するシングルサインオンのサポートが組み込まれています。これは、Red Hat Single Sign-On を使用する場合に有効にしないでください。

3.1.3.2. JSESSIONID cookie の SameSite 値の設定

ブラウザーは、cookie の SameSite 属性の値を Lax に設定することを計画しています。この設定は、リクエストが同じドメインにある場合にのみ、cookie がアプリケーションに送信されることを意味します。この動作は SAML POST バインディングに影響を与える可能性があり、機能しなくなる可能性があります。SAML アダプターのすべての機能を保持するには、コンテナーによって作成された JSESSIONID クッキーの SameSite の値を None に設定することを推奨します。このように設定しないと、Red Hat Single Sign-On へのリクエストごとに、コンテナーのセッションがリセットされる可能性があります。

注記

SameSite 属性を None に設定しないようにするには、許容できる場合は REDIRECT バインディングに切り替えるか、この回避策が不要な場合は OIDC プロトコルに切り替えることを検討してください。

Wildfly/EAP の JSESSIONID cookie の SameSite 値を None に設定するには、以下の内容の undertow-handlers.conf ファイルをアプリケーションの WEB-INF ディレクトリーに追加します。

samesite-cookie(mode=None, cookie-pattern=JSESSIONID)

この設定のサポートは、バージョン 19.1.0 以降の Wildfly で利用可能です。

3.1.4. RPM からの JBoss EAP 7 アダプターのインストール

注記

Red Hat Enterprise Linux 7 では、チャンネル という用語はリポジトリーという用語に置き換えられました。これらの手順では、リポジトリーという用語のみが使用されています。

前提条件

RPM から EAP 7 アダプターをインストールする前に、JBoss EAP 7 リポジトリーにサブスクライブする必要があります。

  • Red Hat Subscription Manager を使用して、Red Hat Enterprise Linux システムがお使いのアカウントに登録されている必要があります。詳細は、Red Hat Subscription Management のドキュメント を参照してください。
  • すでに別の JBoss EAP リポジトリーにサブスクライブしている場合は、最初にそのリポジトリーからサブスクライブを解除する必要があります。

    Red Hat Enterprise Linux 6、7 の場合: Red Hat Subscription Manager を使用して、以下のコマンドで JBoss EAP 7.4 リポジトリーにサブスクライブします。お使いの Red Hat Enterprise Linux のバージョンに応じて、<RHEL_VERSION> を 6 または 7 に置き換えてください。

    $ sudo subscription-manager repos --enable=jb-eap-7-for-rhel-<RHEL_VERSION>-server-rpms

    Red Hat Enterprise Linux 8 の場合: Red Hat Subscription Manager を使用して、以下のコマンドで JBoss EAP 7.4 リポジトリーにサブスクライブします。

    $ sudo subscription-manager repos --enable=jb-eap-7.4-for-rhel-8-x86_64-rpms --enable=rhel-8-for-x86_64-baseos-rpms --enable=rhel-8-for-x86_64-appstream-rpms

手順

  1. Red Hat Enterprise Linux のバージョンに応じて SAML の EAP 7 アダプターをインストールします。

    • Red Hat Linux 7 へのインストール

      $ sudo yum install eap7-keycloak-saml-adapter-sso7_6
    • Red Hat Enterprise Linux 8 へのインストール

      $ sudo dnf install eap7-keycloak-adapter-sso7_6
      注記

      RPM インストールのデフォルトの EAP_HOME パスは /opt/rh/eap7/root/usr/share/wildfly です。

  2. SAML モジュールのインストールスクリプトを実行します。

    $ $EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install-saml.cli

インストールが完了します。

3.1.5. RPM からの JBoss EAP 6 アダプターのインストール

注記

Red Hat Enterprise Linux 7 では、チャンネル という用語はリポジトリーという用語に置き換えられました。これらの手順では、リポジトリーという用語のみが使用されています。

前提条件

RPM から EAP 6 アダプターをインストールする前に、JBoss EAP 6 リポジトリーにサブスクライブする必要があります。

  • Red Hat Subscription Manager を使用して、Red Hat Enterprise Linux システムがお使いのアカウントに登録されている必要があります。詳細は、Red Hat Subscription Management のドキュメント を参照してください。
  • すでに別の JBoss EAP リポジトリーにサブスクライブしている場合は、最初にそのリポジトリーからサブスクライブを解除する必要があります。
  • Red Hat Subscription Manager を使用して、以下のコマンドを使用して JBoss EAP 6 リポジトリーにサブスクライブします。お使いの Red Hat Enterprise Linux のバージョンに応じて、<RHEL_VERSION> を 6 または 7 に置き換えてください。

    $ sudo subscription-manager repos --enable=jb-eap-6-for-rhel-<RHEL_VERSION>-server-rpms

手順

  1. 以下のコマンドを使用して、SAML 用の EAP 6 アダプターをインストールします。

    $ sudo yum install keycloak-saml-adapter-sso7_6-eap6
    注記

    RPM インストールのデフォルトの EAP_HOME パスは /opt/rh/eap6/root/usr/share/wildfly です。

  2. SAML モジュールのインストールスクリプトを実行します。

    $ $EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install-saml.cli

インストールが完了します。

3.1.5.1. WAR のセキュリティー保護

このセクションでは、WAR パッケージ内に設定ファイルを追加してファイルを編集することにより、WAR を直接保護する方法について説明します。

最初に、WAR の WEB-INF ディレクトリーに keycloak-saml.xml アダプター設定ファイルを作成する必要があります。この設定ファイルの形式は、一般的なアダプター設定 セクションで説明されています。

次に、web.xmlauth-methodKEYCLOAK-SAML に設定する必要があります。また、標準のサーブレットセキュリティーを使用して URL に role-base 制約を指定する必要があります。以下は web.xml ファイルの例です。

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
      version="3.0">

	<module-name>customer-portal</module-name>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Admins</web-resource-name>
            <url-pattern>/admin/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>admin</role-name>
        </auth-constraint>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Customers</web-resource-name>
            <url-pattern>/customers/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>user</role-name>
        </auth-constraint>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

    <login-config>
        <auth-method>KEYCLOAK-SAML</auth-method>
        <realm-name>this is ignored currently</realm-name>
    </login-config>

    <security-role>
        <role-name>admin</role-name>
    </security-role>
    <security-role>
        <role-name>user</role-name>
    </security-role>
</web-app>

auth-method 設定を除くすべての標準サーブレット設定。

3.1.5.2. Red Hat Single Sign-On SAML サブシステムを使用した WAR のセキュリティー保護

Red Hat Single Sign-On で WAR を保護するために、WAR をオープンする必要はありません。代わりに、Red Hat Single Sign-On SAML Adapter Subsystem 経由で外部からセキュリティーを確保することもできます。KEYCLOAK-SAML を auth-method として指定する必要はありませんが、web.xmlsecurity-constraints を定義する必要があります。ただし、WEB-INF/keycloak-saml.xml ファイルを作成する必要はありません。このメタデータは、サーバーの サブシステム設定 domain.xml または standalone.xml の XML 内で定義されます。

<extensions>
  <extension module="org.keycloak.keycloak-saml-adapter-subsystem"/>
</extensions>

<profile>
  <subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1">
    <secure-deployment name="WAR MODULE NAME.war">
      <SP entityID="APPLICATION URL">
        ...
      </SP>
    </secure-deployment>
  </subsystem>
</profile>

secure-deployment name 属性は、セキュリティーを保護する WAR を識別します。この値は web.xml.war を追加した module-name です。残りの設定は、一般的なアダプター設定 で定義される keycloak-saml.xml 設定と同じ XML 構文を使用します。

設定例:

<subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1">
  <secure-deployment name="saml-post-encryption.war">
    <SP entityID="http://localhost:8080/sales-post-enc/"
        sslPolicy="EXTERNAL"
        nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
        logoutPage="/logout.jsp"
        forceAuthentication="false">
      <Keys>
        <Key signing="true" encryption="true">
          <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
            <PrivateKey alias="http://localhost:8080/sales-post-enc/" password="test123"/>
            <Certificate alias="http://localhost:8080/sales-post-enc/"/>
          </KeyStore>
        </Key>
      </Keys>
      <PrincipalNameMapping policy="FROM_NAME_ID"/>
      <RoleIdentifiers>
        <Attribute name="Role"/>
      </RoleIdentifiers>
      <IDP entityID="idp">
        <SingleSignOnService signRequest="true"
            validateResponseSignature="true"
            requestBinding="POST"
            bindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"/>

        <SingleLogoutService
            validateRequestSignature="true"
            validateResponseSignature="true"
            signRequest="true"
            signResponse="true"
            requestBinding="POST"
            responseBinding="POST"
            postBindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"
            redirectBindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"/>
        <Keys>
          <Key signing="true" >
            <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
              <Certificate alias="saml-demo"/>
            </KeyStore>
          </Key>
        </Keys>
      </IDP>
    </SP>
   </secure-deployment>
</subsystem>

3.1.6. Java Servlet フィルターアダプター

サーブレットプラットフォーム用のアダプターを持たない Java サーブレットアプリケーションで SAML を使用する場合は、Red Hat Single Sign-On が持つサーブレットフィルターアダプターを使用することを選択できます。このアダプターは、他のアダプターとは異なります。一般的なアダプター設定 セクションに定義されているように /WEB-INF/keycloak-saml.xml ファイルを指定する必要がありますが、web.xml でセキュリティー制約を定義する必要はありません。代わりに、Red Hat Single Sign-On サーブレットフィルターアダプターを使用してフィルターマッピングを定義し、セキュリティーを保護する url パターンを保護します。

注記

Backchannel ログアウトの動作は、標準アダプターとは少々異なります。HTTP セッションを無効にする代わりに、セッション ID をログアウトとしてマークします。セッション ID に基づいて http セッションを任意に無効にする方法はありません。

警告

SAML フィルターを使用するクラスター化されたアプリケーションがある場合は、バックチャネルログアウトは現在機能しません。

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
      version="3.0">

	<module-name>customer-portal</module-name>

    <filter>
        <filter-name>Keycloak Filter</filter-name>
        <filter-class>org.keycloak.adapters.saml.servlet.SamlFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Keycloak Filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

Red Hat Single Sign-On フィルターには、他のアダプターと同じ設定パラメーターがあります。ただし、これらはコンテキストパラメーターではなく、フィルター init パラメーターとして定義する必要があります。

さまざまな異なる安全な URL パターンと安全でない URL パターンがある場合は、複数のフィルターマッピングを定義できます。

警告

/saml に対応するフィルターマッピングがある。このマッピングは、すべてのサーバーコールバックに対応します。

IdP で SP を登録する場合は、http[s]://hostname/{context-root}/saml を Assert Consumer Service URL および Single Logout Service URL として登録する必要があります。

このフィルターを使用するには、この maven アーティファクトを WAR pom に組み込みます。

<dependency>
   <groupId>org.keycloak</groupId>
   <artifactId>keycloak-saml-servlet-filter-adapter</artifactId>
   <version>18.0.18.redhat-00001</version>
</dependency>

マルチテナント を使用するには、keycloak.config.resolver パラメーターをフィルターパラメーターとして渡す必要があります。

    <filter>
        <filter-name>Keycloak Filter</filter-name>
        <filter-class>org.keycloak.adapters.saml.servlet.SamlFilter</filter-class>
        <init-param>
            <param-name>keycloak.config.resolver</param-name>
            <param-value>example.SamlMultiTenantResolver</param-value>
        </init-param>
    </filter>

3.1.7. ID プロバイダーを使用した登録

サーブレットベースのアダプターごとに、アサートコンシューマーサービス URL およびシングルログアウトサービスに登録するエンドポイントは /saml が追加されたサーブレットアプリケーションのベース URL、つまり https://example.com/contextPath/saml である必要があります。

3.1.8. ログアウト

Web アプリケーションからログアウトする方法は複数あります。Jakarta EE サーブレットコンテナーでは、HttpServletRequest.logout() を呼び出すことができます。他のブラウザーアプリケーションでは、ブラウザーをセキュリティー制約のある Web アプリケーションの任意の URL に指定し、クエリーパラメーター GLO (つまり http://myapp?GLO=true) に渡すことができます。ブラウザーに SSO セッションがある場合は、ログアウトします。

3.1.8.1. クラスター化された環境でのログアウト

SAML アダプターは内部的には、SAML セッションインデックス、プリンシパル名 (既知の場合)、および HTTP セッション ID 間のマッピングを保存します。このマッピングは、分散可能なアプリケーションのクラスター全体で、JBoss アプリケーションサーバーファミリー (WildFly 10/11、EAP 6/7) で維持できます。前提条件として、HTTP セッションをクラスター全体に分散する必要があります (つまり、アプリケーションはアプリケーションの web.xml<distributable/> タグでマークされます)。

この機能を有効にするには、以下のセクションを /WEB_INF/web.xml ファイルに追加します。

EAP 7 (WildFly 10/11) の場合:

<context-param>
    <param-name>keycloak.sessionIdMapperUpdater.classes</param-name>
    <param-value>org.keycloak.adapters.saml.wildfly.infinispan.InfinispanSessionCacheIdMapperUpdater</param-value>
</context-param>

EAP 6 の場合:

<context-param>
    <param-name>keycloak.sessionIdMapperUpdater.classes</param-name>
    <param-value>org.keycloak.adapters.saml.jbossweb.infinispan.InfinispanSessionCacheIdMapperUpdater</param-value>
</context-param>

デプロイメントのセッションキャッシュの名前が deployment-cache の場合、SAML マッピングに使用されるキャッシュの名前が deployment-cache.ssoCache になります。キャッシュの名前は、コンテキストパラメーター keycloak.sessionIdMapperUpdater.infinispan.cacheName で上書きできます。キャッシュを含むキャッシュコンテナーはデプロイメントセッションキャッシュを含むものと同じですが、コンテキストパラメーター keycloak.sessionIdMapperUpdater.infinispan.containerName で上書きできます。

デフォルトでは、SAML マッピングキャッシュの設定はセッションキャッシュから派生します。この設定は、他のキャッシュと同じように、サーバーのキャッシュ設定セクションで手動でオーバーライドできます。

現在、信頼できるサービスを提供するには、SAML セッションキャッシュにレプリケートされたキャッシュを使用することが推奨されます。分散キャッシュを使用すると、SAML のログアウト要求が HTTP セッションマッピングへの SAML セッションインデックスにアクセスできないノードに到達する結果となり、ログアウトに失敗する可能性があります。

3.1.8.2. クロスサイトシナリオにおけるログアウト

サイトの間のシナリオは、WildFly 10 以降および EAP 7 以降にのみ適用されます。

複数のデータセンターにまたがるセッションを処理するには、特別な処理が必要です。以下のシナリオを見てみましょう。

  1. ログイン要求は、データセンター 1 のクラスター内で処理されます。
  2. 管理者は、特定の SAML セッションに対してログアウト要求を発行し、要求はデータセンター 2 に送信されます。

データセンター 2 は、データセンター 1 (および HTTP セッションを共有する他のすべてのデータセンター) にあるすべてのセッションをログアウトする必要があります。

この場合、上記 の SAML セッションキャッシュを個別のクラスター内だけでなく、スタンドアロン Infinispan/JDG サーバーを介して すべてのデータセンターにレプリケートする必要があります。

  1. スタンドアロン Infinispan/JDG サーバーにキャッシュを追加する必要があります。
  2. 各 SAML セッションキャッシュのリモートストアとして、以前のアイテムからのキャッシュを追加する必要があります。

デプロイメント中にリモートストアが SAML セッションキャッシュに存在することが検出されると、変更がないか監視され、それに応じてローカル SAML セッションキャッシュが更新されます。

3.1.9. assertion 属性の取得

正常な SAML ログインの後、アプリケーションコードが SAML アサーションで渡される属性値を取得することを推奨します。HttpServletRequest.getUserPrincipal() は、org.keycloak.adapters.saml.SamlPrincipal と呼ばれる Red Hat Single Sign-On 固有のクラスに型変換できる Principal オブジェクトを返します。このオブジェクトを使用すると、raw アサーションを確認でき、属性値を検索するための便利な関数もあります。

package org.keycloak.adapters.saml;

public class SamlPrincipal implements Serializable, Principal {
    /**
     * Get full saml assertion
     *
     * @return
     */
    public AssertionType getAssertion() {
       ...
    }

    /**
     * Get SAML subject sent in assertion
     *
     * @return
     */
    public String getSamlSubject() {
        ...
    }

    /**
     * Subject nameID format
     *
     * @return
     */
    public String getNameIDFormat() {
        ...
    }

    @Override
    public String getName() {
        ...
    }

    /**
     * Convenience function that gets Attribute value by attribute name
     *
     * @param name
     * @return
     */
    public List<String> getAttributes(String name) {
        ...

    }

    /**
     * Convenience function that gets Attribute value by attribute friendly name
     *
     * @param friendlyName
     * @return
     */
    public List<String> getFriendlyAttributes(String friendlyName) {
        ...
    }

    /**
     * Convenience function that gets first  value of an attribute by attribute name
     *
     * @param name
     * @return
     */
    public String getAttribute(String name) {
        ...
    }

    /**
     * Convenience function that gets first  value of an attribute by attribute name
     *
     *
     * @param friendlyName
     * @return
     */
    public String getFriendlyAttribute(String friendlyName) {
        ...
    }

    /**
     * Get set of all assertion attribute names
     *
     * @return
     */
    public Set<String> getAttributeNames() {
        ...
    }

    /**
     * Get set of all assertion friendly attribute names
     *
     * @return
     */
    public Set<String> getFriendlyNames() {
        ...
    }
}

3.1.10. エラー処理

Red Hat Single Sign-On には、サーブレットベースのクライアントアダプターに対するエラー処理機能があります。認証でエラーが発生した場合、クライアントアダプターは HttpServletResponse.sendError() を呼び出します。web.xml ファイル内に error-page を設定して、必要なエラーを処理できます。クライアントアダプターは 400、401、403、および 500 のエラーを出力できます。

<error-page>
    <error-code>403</error-code>
    <location>/ErrorHandler</location>
</error-page>

クライアントアダプターは、取得可能な HttpServletRequest 属性も設定します。属性名は org.keycloak.adapters.spi.AuthenticationError です。このオブジェクトは、org.keycloak.adapters.saml.SamlAuthenticationError に型変換されます。このクラスは、何が起こったのかを正確に知ることができます。この属性が設定されていない場合、アダプターはエラーコードを担当しませんでした。

public class SamlAuthenticationError implements AuthenticationError {
    public static enum Reason {
        EXTRACTION_FAILURE,
        INVALID_SIGNATURE,
        ERROR_STATUS
    }

    public Reason getReason() {
        return reason;
    }
    public StatusResponseType getStatus() {
        return status;
    }
}

3.1.11. トラブルシューティング

問題のトラブルシューティングを行う最適な方法として、クライアントアダプターと Red Hat Single Sign-On サーバーの両方で SAML のデバッグをオンにすることができます。ロギングフレームワークを使用して、org.keycloak.saml パッケージのログレベルを DEBUG に設定します。これをオンにすると、サーバーとの間で送受信される SAML 要求および応答ドキュメントを確認できます。

3.1.12. マルチテナンシー

SAML は マルチテナント の OIDC と同じ機能を提供します。つまり、1 つのターゲットアプリケーション (WAR) は複数の Red Hat Single Sign-On レルムでセキュリティー保護されます。レルムは、同じ Red Hat Single Sign-On インスタンスまたは別のインスタンスに配置できます。

これを実行するには、複数の keycloak-saml.xml アダプター設定ファイルが必要です。

異なるアダプター設定ファイルを含む WAR の複数のインスタンスを異なるコンテキストパスにデプロイすることができますが、これは不便である可能性があるため、コンテキストパス以外のものに基づいてレルムを選択することを推奨します。

Red Hat Single Sign-On では、カスタム設定リゾルバーの設定が可能で、これにより、リクエストごとに使用するアダプター設定を選択できるようになります。SAML では、設定はログイン処理のみに関連し、ユーザーがログインするとセッションが認証され、返された keycloak-saml.xml が異なるかどうかは問題ありません。そのため、同じセッションで同じ設定を返すことが、適切な方法になります。

そのためには、org.keycloak.adapters.saml.SamlConfigResolver の実装を作成します。以下の例では、Host ヘッダーを使用して適切な設定を検索し、アプリケーションの Java クラスパスから関連する要素を読み込みます。

package example;

import java.io.InputStream;
import org.keycloak.adapters.saml.SamlConfigResolver;
import org.keycloak.adapters.saml.SamlDeployment;
import org.keycloak.adapters.saml.config.parsers.DeploymentBuilder;
import org.keycloak.adapters.saml.config.parsers.ResourceLoader;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.saml.common.exceptions.ParsingException;

public class SamlMultiTenantResolver implements SamlConfigResolver {

    @Override
    public SamlDeployment resolve(HttpFacade.Request request) {
        String host = request.getHeader("Host");
        String realm = null;
        if (host.contains("tenant1")) {
            realm = "tenant1";
        } else if (host.contains("tenant2")) {
            realm = "tenant2";
        } else {
            throw new IllegalStateException("Not able to guess the keycloak-saml.xml to load");
        }

        InputStream is = getClass().getResourceAsStream("/" + realm + "-keycloak-saml.xml");
        if (is == null) {
            throw new IllegalStateException("Not able to find the file /" + realm + "-keycloak-saml.xml");
        }

        ResourceLoader loader = new ResourceLoader() {
            @Override
            public InputStream getResourceAsStream(String path) {
                return getClass().getResourceAsStream(path);
            }
        };

        try {
            return new DeploymentBuilder().build(is, loader);
        } catch (ParsingException e) {
            throw new IllegalStateException("Cannot load SAML deployment", e);
        }
    }
}

また、web.xml のコンテキストパラメーター keycloak.config.resolver で使用する SamlConfigResolver 実装を設定する必要があります。

<web-app>
    ...
    <context-param>
        <param-name>keycloak.config.resolver</param-name>
        <param-value>example.SamlMultiTenantResolver</param-value>
    </context-param>
</web-app>
Red Hat logoGithubRedditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

© 2024 Red Hat, Inc.