第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 ポリシーです。有効な値は
ALL
、EXTERNAL
、および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-With
、SOAPAction
、またはAccept
などの一般的なヘッダーに基づいて SOAP クライアントまたは REST クライアントを自動検出します。デフォルト値は false です。 - logoutPage
-
これにより、ログアウト後に表示するページが設定されます。ページが
http://web.example.com/logout.html
などの完全な URL の場合、ユーザーは HTTP302
ステータスコードを使用してログアウト後にそのページにリダイレクトされます。スキーム部分のないリンク (例:/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
要素内で、PrivateKeyPem
、PublicKeyPem
および 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
が、roleA
、roleB
、および roleC
があるアサーションから抽出されると、プリンシパルに割り当てられたロールの最終セットは roleC
、roleX
、roleY
、および roleZ
になります。なぜなら roleA
が roleX
および 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 Guideの SAML 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_SHA1
、RSA_SHA256
、RSA_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
) で終了する必要があります。このプロパティーの値は SAMLAuthnRequest
メッセージの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 キーストアの公開証明書を抽出して、このトラストストアを作成できます。これは、disableTrustManager
がtrue
でない限り 必須 になります。 - 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 のダウンロードサイトの個別ダウンロードです。
手順
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 モジュールを作成します。
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
手順
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 です。
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
手順
以下のコマンドを使用して、SAML 用の EAP 6 アダプターをインストールします。
$ sudo yum install keycloak-saml-adapter-sso7_6-eap6
注記RPM インストールのデフォルトの EAP_HOME パスは /opt/rh/eap6/root/usr/share/wildfly です。
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.xml
で auth-method
を KEYCLOAK-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.xml
で security-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 のクラスター内で処理されます。
- 管理者は、特定の SAML セッションに対してログアウト要求を発行し、要求はデータセンター 2 に送信されます。
データセンター 2 は、データセンター 1 (および HTTP セッションを共有する他のすべてのデータセンター) にあるすべてのセッションをログアウトする必要があります。
この場合、上記 の SAML セッションキャッシュを個別のクラスター内だけでなく、スタンドアロン Infinispan/JDG サーバーを介して すべてのデータセンターにレプリケートする必要があります。
- スタンドアロン Infinispan/JDG サーバーにキャッシュを追加する必要があります。
- 各 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>