KeycloakをブローカーにしてMicrosoft ADFSとSAML v2.0で連携する構成は、エンタープライズでいまも現役です。ただ「メタデータをインポートしたのにログインできない」で止まる案件が後を絶ちません。本記事では、SP/IdPメタデータ、署名と暗号化、NameID形式、時刻ずれ、証明書ローテ、属性マッピングという定番の落とし穴を、現場で切り分けている順番のまま整理します。

KeycloakはOIDCプロバイダとして語られることが多いのですが、エンタープライズの現場では「既存のADFS(Active Directory Federation Services)とSAMLで繋ぎ、下流のアプリにはOIDCで配る」ブローカー構成が根強く残っています。SAML v2.0という枯れた仕様同士の接続にもかかわらず、実際にやると同じ場所で必ずつまずきます。本記事はその「必ずつまずく場所」を、私たちが切り分けている順序のまま並べたものです。バージョンは現行のQuarkus版Keycloak(新しめのバージョン基準)を前提にしますが、SAMLブローカーの設定項目自体はWildFly版時代から大きくは変わっていません。細部は必ず公式ドキュメントで確認してください。

01まず全体像:ブローカーとしてのKeycloak

用語を最初に固定します。KeycloakがADFSと話すとき、KeycloakはSP(Service Provider)側、ADFSがIdP(Identity Provider)側です。一方で下流のアプリから見ると、KeycloakがIdPになります。つまりKeycloakは「上流にはSPの顔、下流にはIdPの顔」を持つ二枚舌です。この立ち位置を取り違えると、どちらのメタデータをどちらに渡すのかで延々と混乱します。

ADFS 上流 IdP Keycloak 上流に対して SP 下流に対して IdP 業務アプリ 下流 SP(OIDC等) SAML v2 OIDC / SAML Keycloak は二枚舌:上流SP / 下流IdP
図:ADFSをIdP、Keycloakを「上流SP・下流IdP」とするブローカー構成。メタデータの向きを取り違えないことが第一歩です。

この二枚舌ゆえに、証明書も鍵も「上流用」と「下流用」で別々に存在します。トラブル時に「どの証明書の話をしているのか」を常に意識するだけで、切り分けの速度が段違いになります。

02メタデータの向きと、インポートしても直らない値

KeycloakのAdmin ConsoleでIdentity Providersから「SAML v2.0」を追加し、ADFSのフェデレーションメタデータURL(典型的には https://fs.example.com/FederationMetadata/2007-06/FederationMetadata.xml)を入力して「Import」すると、エンドポイントURLや署名証明書がフォームに自動投入されます。Keycloak公式のADFS連携ガイドもこの手順を前提にしています。ここまでは誰でも通ります。

問題は、インポートで自動投入される値と、手で合わせるべき値が混在している点です。エンドポイントや署名証明書は取り込めますが、NameID Policy Formatや後述のPrincipal Type、署名鍵名ヒントなどは、ADFS側の挙動を見ながら手で決める必要があります。「インポートしたのだから全部合っているはず」という思い込みが、最初のハマりどころです。

逆向き、つまりKeycloak(SP)のメタデータをADFSに渡す作業も必要です。Keycloakは各IdP設定に対してSP記述子(entity descriptor)を公開するエンドポイントを持っており、そのdescriptor URLをADFSのRelying Party Trust(証明書利用者信頼)に登録します。ADFS側は「Claims aware」の信頼として作るのが基本です。

現場のコツ:メタデータをインポートしたら、そのままにせず生成された値を一つずつ目視で確認します。特にSingle Sign-On Service URL(HTTP-POSTかRedirectか)と署名証明書のフィンガープリントは、ADFS側の実物と突き合わせておくと後の切り分けが速くなります。

03署名と暗号化:ONにする場所を間違えない

SAMLの署名検証は、設定項目が多く方向がややこしいので、意味を分けて押さえます。Keycloakのブローカー設定には主に次の項目があります(公式のsaml.adocが一次情報です)。

ADFSは既定で署名済みのレスポンス/Assertionを返してくるため、実務ではValidate SignatureをONにして運用するのが定石です。ここで頻発するのが、Want AuthnRequests SignedをONにしたのにADFS側が署名を検証できない、というケース。ADFSは署名鍵の識別に証明書のSubjectを見るため、Keycloak側のSAML Signature Key NameCERT_SUBJECT に設定する必要があります。既定値(KEY_ID)のままだとADFSがキーを解決できず、リクエストを弾きます。これは公式ADFSガイドでも明記されている、ADFS特有の勘所です。

署名アルゴリズムにも注意します。Keycloakの既定はRSA_SHA256方向ですが、古いADFS運用でSHA-1前提の設定が残っていると噛み合いません。新規構築ではSHA-256系で揃え、SHA-1は互換目的以外で使わない方針が無難です。

04NameID形式とPrincipal Type:ログインできない8割はここ

「メタデータも証明書も合っているのにブローカーログインが失敗する」——その大半はNameID形式とPrincipal Typeの不一致です。

KeycloakのNameID Policy Formatの既定は urn:oasis:names:tc:SAML:2.0:nameid-format:persistent です。一方でADFSは、クレームルールの組み方によってNameIDに何を載せるかが変わります。公式ADFSガイドが「Windows Domain Qualified Name形式」を例に挙げているのはそのためで、Keycloakが要求する形式とADFSが実際に返す形式がずれると、Assertionは来ているのにユーザ識別に失敗します

ここで効くのがPrincipal Typeです。ユーザの一意識別に「Subject NameID」を使うか、「SAML attribute(属性名/フレンドリ名指定)」を使うかを選べます。ADFSがNameIDに安定した値を載せない運用のとき、UPNやemailといった属性を主キーに使う設計へ切り替えると一気に安定します。なお、Subject NameID値の固定と transient 形式は併用できない、といった仕様上の制約もあるため、要件に応じて選びます。

現場のコツ:形式を推測で合わせないこと。ブラウザのSAML Tracer等で実際のSAMLResponseを1回キャプチャし、<NameID Format="..."><AttributeStatement> の中身を目で確認してからKeycloak側を合わせます。「実物を1回見る」だけで往復回数が激減します。

05時刻ずれ(Clock Skew):一番地味で一番多い

SAMLのAssertionには NotBeforeNotOnOrAfter の時刻窓が入っており、SPは「NotBefore ≦ 現在時刻 < NotOnOrAfter」を検証します。KeycloakとADFSの時計がずれると、発行直後のAssertionが「まだ有効になっていない」あるいは「すでに期限切れ」と判定され、正しい認証が理不尽に落ちます。Cloud-IAMの解説が挙げる例のとおり、SP側が数分進んでいるだけで5分有効のAssertionが即座に失効扱いになります。

対策は二段構えです。第一に、両系をNTPで確実に同期させること。仮想化基盤やコンテナでホスト時刻がずれるのは珍しくありません。第二に、Keycloakのブローカー設定にあるAllowed clock skew(許容時刻ずれ、秒)に適切な余裕を持たせること。おおむね30〜120秒が実務的な落としどころで、大きくしすぎるとリプレイ耐性が下がるのでバランスを取ります。

この症状のいやらしさは「昨日まで動いていたのに突然落ちる」形で出る点です。NTPが外れた、コンテナを別ホストに移した、タイムゾーン設定を触った——認証以外の変更が引き金になるため、認証まわりだけ見ていると原因にたどり着けません。切り分けの初手として「両系のdateを突き合わせる」を習慣にしておくと事故が減ります。

06証明書ローテーション:期限切れは深夜に来る

ADFSのトークン署名証明書は、既定で自動ロールオーバーが有効なことが多く、放っておくと一定周期で更新されます。Keycloak側がメタデータURLから署名証明書を都度取得する設定であれば追随できますが、証明書をメタデータからではなく手動で貼り付けている構成だと、ADFSのローテーションと同時に署名検証が全面的に失敗します。移行案件で引き継いだ環境がまさにこれで、ある朝いきなり全社ログイン不可、というのが典型的な事故です。

証明書は「切れる日が確実に来るのに、切れた瞬間まで誰も見ていない」性質の資産です。ローテーションを人手の記憶に依存させないことが、認証基盤の可用性設計そのものになります。監視の考え方は監視・アラート設計の記事も参考にしてください。

07属性マッピング:クレームURIを正しく橋渡しする

認証が通ったら、次はADFSが送るクレームをKeycloakのユーザ属性・ロールに落とし込みます。ADFSはWS系のクレームURIで属性を送るため、Keycloak側のIdP MapperでこのURIを受けます。公式ガイドが示す代表例は次のとおりです。

ADFS側では「Send LDAP Attributes as Claims」ルールでADの属性をクレーム化し、必要に応じてTransformルールで整形します。ここでの定番トラブルは、属性名の完全一致です。SAMLのAttribute Nameは大文字小文字・末尾スラッシュ・NameFormat(URI形式か基本形式か)まで含めて一致させる必要があり、1文字違うだけでマッピングは黙って空になります。ロールが付かない・メールが空、という症状のときは、まず実際のAssertionのAttribute Nameとマッパー設定を1文字ずつ突き合わせます。

グループからロールへの変換は、下流アプリの認可設計に直結します。KeycloakでADのグループをそのままロール化すると粒度が粗くなりがちなので、ロール設計・グループ設計は下流要件から逆算するのが定石です。設計観点はLDAP/AD連携アイデンティティブローカリングの記事も合わせてご覧ください。

08SAMLか、OIDCか:新規なら基準を持って選ぶ

最後に選択の話です。ADFSと繋ぐ既存要件があるならSAML一択ですが、新規で下流アプリを組むなら判断が要ります。実務的な基準はシンプルです。

Keycloakのブローカー構成が優れているのは、上流はSAMLで受け、下流にはOIDCで配る変換点になれる点です。ADFSという資産を活かしつつ、新規アプリはモダンなOIDCで実装できる。この「レガシーとモダンの緩衝材」としてKeycloakを置く設計は、移行期のエンタープライズで非常に相性が良いアプローチです。OIDC側の設計はOIDCの各グラントも参考になります。

まとめ

KeycloakとADFSのSAML連携は、仕様が枯れているぶん「合わせるべき値を1つずつ正確に合わせる」作業に尽きます。メタデータの向き、署名のON/OFFと鍵名ヒント(CERT_SUBJECT)、NameID形式とPrincipal Type、時刻ずれ、証明書ローテ、属性のクレームURI完全一致——このどれか1つがずれるだけでログインは落ちます。逆に言えば、この6点を切り分けの順番として持っておけば、原因究明は驚くほど速くなります。私たちはこの構成をエンタープライズの認証基盤として実構築しており、移行案件の「引き継いだら証明書が切れて全社ログイン不可」まで含めて対応しています。実際の進め方は導入事例もご覧ください。

参考(一次情報)

SAML/ADFS連携やKeycloakによる認証基盤の設計・移行でお困りの際は、実構築の経験をふまえてお問い合わせください。

相談する
← ブログ一覧へ戻る