概要と結論
-
Microsoft Entra ID→Amazon Cognito→アプリケーションをSAML連携したところ、サインインに失敗 - 該当ユーザー(筆者)の表示名に4バイトのUTF-8文字が含まれていた
- CognitoはIdPから渡されるSAML属性値に4バイトUTF-8文字が含まれると受け付けないという仕様があり、ドキュメントにも明記されていた
- 対応としてCognitoが参照する属性から「表示名」等の4バイト文字を除外することで解決
- RPで4バイト文字を含む属性値を利用したい場合:
- エラー回避さえ出来れば良い場合、Entra IDでは
RegexReplace機能で4バイト文字を記号(■等)に置換する方法が最も簡単 - 別ルート(Microsoft Graph API等)でアプリ側から取得する方法も有効
- Base64エンコード(Lambda等のプロキシ)も可能だが実装コストが高い
- エラー回避さえ出来れば良い場合、Entra IDでは
背景構成
- IdP: Microsoft Entra ID
- SP: Amazon Cognito User Pool
- RP: 社内向けアプリケーション
- ALBのリスナールールにCognitoを適用
認証フロー:
- ユーザーがアクセス
- ALBがCognitoの
/oauth2/authorizeにリダイレクト - CognitoがEntraIDのSAMLエンドポイントにリダイレクト
- EntraIDからCognitoに
SAMLResponsePOST - Cognitoがトークンを発行し、
/oauth2/idpresponseにリダイレクト - 社内向けアプリケーションへ到達
発生した症状〜解決まで
- 開発中にあるユーザー(筆者)がサインインすると、次のような挙動:
- EntraIDのサインイン画面
- 認証情報を入れると Cognito側で
401 Authorization Requiredエラーになり、アプリケーションまで戻ってこない
- ブラウザ上では、Cognito のホスト型ドメイン配下であり、エラーは出るが原因までは明示されない
- Cognito側で認識しているSAML証明書はEntra IDの正しい物
- 期限も問題ない
- Entra ID側でサインイン自体は成功していることがログには出ている
→ 🎄原因の当たりがない🎄
- デベロッパツールのNetworkタブでSAMLResponseの中身を見る
-
status:Successになっている
-
- ChatGPTにもSAMLResponseを読んでもらうと原因を推測し以下の情報を教えてもらう
Amazon Cognito では、IdP が属性値として渡す 4 バイトの UTF-8 文字 (😐 や 𠮷 など) は受け付けません。文字を Base 64 にエンコードしてテキストとして渡し、アプリでデコードできます。
https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/cognito-user-pools-saml-idp-things-to-know.html
今回とった対応
- 4バイト文字が含まれる可能性のある属性値を除去
- 筆者は氏名に4バイト文字が含まれる自覚を強めた
RPで4バイト文字が含まれる属性値を利用したい場合はどうする
- 別ルート(DB等)で渡す
- SAML認証の構成に認証以外の意味を持たせないで済むのでこちらが好き
- ドキュメントの通りBase64にエンコードしてテキストとして渡す
-
Amazon Cognito では、IdP が属性値として渡す 4 バイトの UTF-8 文字 (😐 や 𠮷 など) は受け付けません。文字を Base 64 にエンコードしてテキストとして渡し、アプリでデコードできます。
https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/cognito-user-pools-saml-idp-things-to-know.html
-
- 属性値をカスタムする
Base64エンコードして渡す
Microsoft Entra IDには属性値をbase64にエンコードする機能は存在しません。(執筆当時)
他のSaaS型IdPも標準機能としては無さそうです。
その場合カスタムでプロキシサーバーを用意する必要があります。
属性値をカスタムする
Microsoft Entra IDには属性値をカスタムする機能があり、値の正規表現置換が出来ます。
4バイト文字を▪︎等の記号で置き換えることによりエラー回避は出来そうなのでやってみました。
無事認証完了後にRPへ到達しました。
デベロッパツールで取得したSAMLResponseを見てみると、
<Attribute Name="surname"><AttributeValue>■富</AttributeValue></Attribute>
正しく置換されていました。
属性値の利用用途によってはプロキシ立てずとも、こちらで十分そうです。
