この記事は2024/11/25に作成しています。CognitoのUIが切り替わった時期で、従来の手順とも変わっているので、正確ではない記述が含まれている可能性もあります。
はじめに
弊社は Amazon Cognitoを利用しているSaaSとAzure AD B2Cを利用しているSaaSを開発しています。
この2つのサービスは独立しており、それぞれのサービスが認証機能やユーザー管理を持っています。
また、それぞれのサービスが独自のユーザー管理方式と外部のIdPを活用したシングルサインオン(SSO)の仕組みを持っています。この2つのサービスは、Google認証やAzure Entra ID認証を利用すればSSOはできていました。ですが、独自のユーザー管理方式でもSSOを行いたいという要件が出てきました。
この要件を実現する手段として、独自のユーザー管理をAmazon Cognitoで行い、それぞれのサービスのSSO(OIDC(Open ID Connect))の仕組みを利用することで、要件を実現しました。この手順をご紹介します。
ゴール
WebアプリがAmazon CognitoやAzure AD B2Cを使えることを前提としています。
Amazon CognitoやAzure AD B2Cの使い方については本記事では対象にしていません。
「BEFORE」のサービス構成を「GOAL」のサービス構成になるようにします。
Identify Provider(Idp):Amazon Cognito
Relying Party (RP) :Amazon CognitoとAzure AD B2C
認証はOIDC(Open ID Connect)で行います。
BEFORE
GOAL
以降の説明では、わかりやすくするためシークレットの値も記載しています。
記事の投稿時には該当の環境は削除しています。
ユーザープール(Amazon Cognito)
以下のユーザープール(userpool-test)が存在しているとします。
※ユーザープールID:ap-northeast-1_VZWZPzQ7e
ユーザープールの作成方法については本記事では触れません。
なお、Eメールで認証を行っているとしています。
また、以下のアプリケーションクライアント(org-app)が作成されているとします。
後述の設定を行うことで、このアプリケーションクライアント(org-app)をRelying Party (RP) の役割にします。
Amazon Cognitoの設定
ここからが本題です。Amazon CognitoでAmazon Cognitoと連携します。
ややこしいですが、CognitoからEntraIDをIdpとして利用するのと同じ考えです。EntraIDではなくCognitoで認証します。
作成したユーザープール(userpool-test)に対して以下の設定を行います。
・Idp用のアプリケーションクライアントの登録
・アイデンティティプロバイダーの登録
Idp用のアプリケーションクライアントの登録
上記のアプリケーションクライアントの画面からIdp用のアプリケーションクライアント(idp-app)を追加します。
アプリケーションタイプは「従来のウェブアプリケーション」を選択してください。
「従来のウェブアプリケーション」を選択することで、クライアントシークレットが発行されたアプリケーションクライアントを作成できます。Idp用のアプリケーションクライアントではクライアントシークレットが必要です。クライアントシークレットは後から発行することはできません。
リターンURL(許可されているコールバックURLのこと)には以下を設定します。
https://ユーザープール名.auth.ap-northeast-1.amazoncognito.com/oauth2/idpresponse
今回の環境では以下になります。
https://userpool-test.auth.ap-northeast-1.amazoncognito.com/oauth2/idpresponse
このURLはCognitoを利用しているサービス向けのコールバックURLです。
Cognitoのエンドポイントについては以下を参考にしてください。
Identity provider and relying party endpoints
上記のようなアプリケーションクライアントを作成します。
アプリケーションクライアントの追加後に「ログインページ」の「編集」ボタンで編集します。以下の設定が行われていることを確認してください。
・IDプロバイダー:Cognitoユーザープールディレクトリ
・OAuth付与タイプ:認証コード付与
・OpenID Connect のスコープ:openid
なお、「許可されているコールバックURL」を追加しています。追加したURLはAzure AD B2Cを利用しているサービス向けのコールバックURLです。「許可されているコールバックURL」の設定は重要です。設定が異なっているとログイン画面が表示されません。以下のURLを設定します。
https://テナント名.b2clogin.com/テナント名.onmicrosoft.com/oauth2/authresp
テナント名は利用するAzure AD B2Cのドメイン名を確認してください。ドメイン名が「xxxxx.onmicrosoft.com」の場合、テナント名が「xxxxx」になります。設定するURLは以下になります。
https://xxxxx.b2clogin.com/xxxxx.onmicrosoft.com/oauth2/authresp
アプリケーションクライアントとしては以下の2つが存在することになります。
アイデンティティプロバイダーの登録
「ソーシャルプロバイダーと外部プロバイダー」でアイデンティティプロバイダーとしてCognitoのユーザープールが使える設定を行います。
※いろいろな「プロバイダー」という言葉がでてきていますね。もう少し統一感があってもいいと思いますが・・・
「アイデンティティプロバイダーを追加」ボタンを押下して、アイデンティティプロバイダーを登録します。
アイデンティティプロバイダーとしては「OpenID Connect(OIDC)」を選択します。
以下の設定を行います。
プロバイダー名:任意の値
クライアントID:
Idp用のアプリケーションクライアント(idp-app)に設定されているクライアントID
クライアントシークレット:
Idp用のアプリケーションクライアント(idp-app)に設定されているクライアントシークレット
許可されたスコープ:openid
属性のリクエストメソッド:GET
セットアップ方法:発行者 URL を通じた自動入力
発行者URL:
https://cognito-idp.ap-northeast-1.amazonaws.com/ユーザープールID
今回の環境では以下になります。
https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_VZWZPzQ7e
上記のようにアイデンティティプロバイダーが登録されます。
以上で、Cognito側の設定は完了のはずです。
Idp用のアプリケーションクライアントでログインページが表示できるか確認してみます。上記の画面で「ログインページを表示」をクリックします。
クリックするとCognitoが用意してくれたログイン画面が表示されるはずですが、
???
Login pages unavailable
Please contact an administrator.
なんでしょう???
ここで、はまりました。
いろいろと確認するとIdp用のアプリケーションクライアントがマネージドログインを使う設定になっているようですが、スタイルが割り当たっていないことが原因でした。マネージドログインの機能は2024/11のアップデートで追加されました。アップデート後に環境を構築したのは今回が初めてだったので、原因を突き止めるのに時間がかかりました。
idp用のアプリケーションクライアントにもスタイルを割り当てたところ、無事にログイン画面が表示されました。
「マネージドログイン」は従来の「ホストされたUI」の機能よりもできることが多くなっており、今後使えそうです。いろいろと試してみたいと思っています。
Azure AD B2Cの設定
さて、次はAzure AD B2CでAmazon Cognitoと連携します。
Azure AD B2Cをすでに使っている場合を想定しているので、Azure AD B2Cの開始方法については触れません。
新しく使う場合は以下の記事などを参考にしてください。
チュートリアル:Azure Active Directory B2C テナントの作成
Azure AD B2Cでは以下の機能を使用します。
・アプリケーションの登録
・OpenID Connectプロバイダーの登録
・ユーザーフローの登録
アプリケーションの登録
まずは「アプリの登録」から新しいアプリケーションを登録します。
以下の設定を行います。
名前:任意の名前
サポートされているアカウントの種類:
任意の ID プロバイダーまたは組織ディレクトリ内のアカウント (ユーザーフローを使用したユーザーの認証用)
リダイレクトURI:
Azure AD B2Cを使うサービスのログイン画面などのURI
※今回はテスト用に「Web」としてhttps://www.amazon.co.jp/を設定しています。
本来は適切なURIを設定する必要があります。
OpenID Connectプロバイダーの登録
「IDプロバイダー」画面で「新しいOpenID Connectプロバイダー」ボタンを押下して、接続先の情報を設定します。
以下の値を設定します。
項目 | 値 |
---|---|
名前 | 任意の名前 |
メタデータ URL | 利用するCognitoのメタデータ URL(*1) |
クライアント ID | Idp用のアプリケーションクライアント(idp-app)のクライアントID |
クライアントシークレット | Idp用のアプリケーションクライアント(idp-app)のクライアントシークレット |
スコープ | openid |
応答の種類 | code |
応答モード | form_post |
ドメインのヒント | |
ユーザーID | sub |
表示名 | name |
名 | |
姓 | |
電子メール |
(*1)
CognitoのメタデータURLは以下になります。
https://cognito-idp.リージョン.amazonaws.com/ユーザープールID/.well-known/openid-configuration
今回の環境では以下になります。
https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_VZWZPzQ7e/.well-known/openid-configuration
再び記載しますが、Cognitoのエンドポイントについては以下を参考にしてください。
Identity provider and relying party endpoints
ユーザーフローの登録
最後にユーザーフローの登録を行います。
「ユーザーフロー」から「新しいユーザーフロー」ボタンを押下します。
ユーザーフロータイプは「サインアップとサインイン」を選択肢、バージョンは「推奨」を選択します。
以下を設定します。
※テスト用の設定を記載しています。使う環境にあわせて設定してください。
名前:任意の名前
ローカルアカウント:None
カスタムIDプロバイダー:cognito ※「IDプロバイダー」で追加したIDプロバイダー名です。
方法の種類:メール
MFAの強制:オフ
条件付きアクセスポリシーを適用する:オフ
ユーザー属性とトークン要求:メールアドレスの「属性を収集する」をオン
ユーザーフローを登録したら、登録されたユーザーフローを選択して、Cognitoに接続できるか確かめます。「ユーザーフローを実行します」のボタンを押下します。
「アプリケーション」と「応答URL」が選択できるので、今回作成したアプリケーションおよび、アプリケーションに登録したリダイレクトURIを選択します。
「ユーザーフローを実行します」のボタンを押下すると、下記のようにCognitoで用意されているログイン画面が表示されます。
検証
Cognitoのユーザープールにユーザーを追加して、Azure AD B2Cのユーザーフローを試してみます。
自分が使えるメールアドレスをユーザーとして登録します。
ユーザーフローを実行し、ログイン画面で登録したメールアドレスおよびパスワードを設定します。最初は仮パスワードの状態なので、検証コードがログインしようとするメールアドレスに送信されます。このあたりのフローも用意してくれるのでいいですね。
ログインに成功すると応答URLに設定されていたアマゾンのページに遷移します。ログアウト処理を実装していないので、再度ユーザーフローを実行した場合は、(サインインされている状態なので)ログイン画面は経由せずにアマゾンのページに遷移されます。
まとめ
弊社では既存サービスのSaaS化を進めていますが、Amazon CognitoもしくはAzure AD B2Cを使っているサービスについては簡単にシングルサインオンが実現できそうです。Amazon CognitoやAzure AD B2Cを使うことで、いろいろなIdpに簡単に対応できるのはすばらしいと改めて感じました。