業務でSSO開発を行ったので、備忘録。
対象者
- Cognitoを使用してSSO連携したい人
- SAML認証を使用してSSO連携したい人
- IdPを簡潔に設定してSSO連携の動きを知りたい人
SSOとは
Single Sign-Onの略で、ユーザーが複数のサービスに一度のログインでアクセスできるようにする技術です。これにより、ユーザーエクスペリエンスが向上し、パスワード管理のオーバーヘッドも削減されます。
SAMLとは
Security Assertion Markup Languageの略で、SSOのためのXMLベースのオープンスタンダードです。SAMLは、異なるドメイン間での認証と承認データの交換を可能にします。
AWS Cognitoとは
Amazon Web Services (AWS) が提供する認証・認可サービスです。Cognitoを使用すると、Webアプリケーションやモバイルアプリケーションに簡単にユーザー管理と認証機能を追加することができます。
実装の流れ
今回は下図を構築していきます。App部分は後日時間があれば別記事にします。
SAML IdPはKeycloakを使用しています。オープンソースのアイデンティティ・アクセス管理ソフトウェアなのでローカル環境で構築できます。
- Cognito設定(ユーザープール作成)
- IdP設定(Keycloak構築)
- Cognitoのアプリケーションクライアント構築
- 動作確認(Cognito アプリケーションクライアントのホストされたUIから確認)
構築
Cognito設定
AWSマネコン > AWS Cognito > ユーザープール作成
ユーザープール作成
SSO連携させたいので「フェデレーテッドアイデンティティプロバイダー」チェック
SSO連携時のマッピングをemailで行うので「Eメール」チェック
フェデレーティッドサインインのオプション:SAML
この辺は適宜設定してください。(今回に影響なし)
パスワードポリシー:Cognitoのデフォルト
IdP(keycloak)設定後に設定するので「後で」クリック
ドメイン名はSSO連携で必要になるため「Cognitoドメインを使用する」にチェック
ドメイン名は任意の値
「パブリッククライアント」チェック
アプリケーションクライアント名:任意の値
クライアントのシークレットを生成しない:チェック
許可されているコールバックURL:https://jwt.io →後から説明します。
作成できました!!ユーザープールIDはkeycloak設定で使用します。
IdP設定(Keycloak構築)
前提:dockerをローカルPCに構築済
今回IdPはローカル環境内に構築していきます。Dockerを使用するので各自構築お願いします。
docker-compose.yaml
version: '3'
services:
keycloak:
image: quay.io/keycloak/keycloak:latest
container_name: keycloak
tty: true
stdin_open: true
ports:
- "18080:8080" # 8080は被りやすいので別のポートに設定
volumes:
- .keycloak:/opt/keycloak/data # DB情報等が格納されます
environment:
KEYCLOAK_ADMIN: admin # 管理ユーザーIDを設定
KEYCLOAK_ADMIN_PASSWORD: admin # 管理ユーザーのパスワードを設定
command:
- start-dev --http-relative-path /auth # 開発モードで起動
Docker起動
$ docker-compose up -d
Keycloak起動
ブラウザで「 http://localhost:18080/auth/ 」入力。以下のように表示されたら成功!!
今からKeycloakの設定を行なっていきます。
Keycloakの細かい内容を知りたい場合は公式ドキュメントを読んでください。
https://keycloak-documentation.openstandia.jp/
IdP側の設定
- レルム作成(多分テナント単位みたいなもの)
- レルムのロール作成
- クライアント作成(今回はCognito側の情報設定)
- IdP内にユーザー追加
「Administration Console >」クリック → Dockerファイルで設定した、ユーザー、PWを入力
レルム作成
サイドメニュー「master」クリック→「Create Realm」クリック
Realm name 「Test」入力、「Create」クリック
サイドメニューから「Realm roles」クリック、「Create role」クリック
「Role name」に「Test-role」入力、「Save」クリック
サイドメニューから「Clients」クリック、「Create client」クリック
下記設定:
Client Type: SAML
Client ID: urn:amazon:cognito:sp:<ユーザープールID>
※ユーザープールIDは各自作成したユーザープールで確認
IdP(Keycloak)は、SAMLアサーションを使用して、このエンドポイントにユーザーをリダイレクトするので以下の設定が必要です。
Keycloak側でCognitoの帰り先を設定するイメージ。
Valid redirect URIs:
https://< yourDomainPrefix >.auth.< region >.amazoncognito.com/saml2/idpresponse
※以下公式ドキュメント参考:https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/cognito-user-pools-saml-idp.html
今回クライアント署名は必要ないため、OFFにします。
「Keys」タブ、「Client signature required」OFF
Service ProviderであるCognitoとIdp(Keycloak)をマッピングしていきます。
「Client scopes」タブから作成したクライアントをクリック、「Configure a new mapper」クリック
Cognitoユーザープールでemailをサインインオプションに設定しているため
下記設定後、「Save」クリック
Name:email
Property:email
Fiendly name: email
SAML Attribute Name: email
サイドメニュー「Clients」から「Clients list」タブクリック、先ほど設定したリストをクリック
SAML設定で認証連携を行うにはユーザーの識別子を連携する必要があります。
同じユーザーを表す際に永続的に同じ識別子が使われる場合、「persistent」となります。
Name ID format:persistent
Force name ID format:ON
サイドメニュー「Realm setting」クリック、「Requlre SSL」:Noneに設定
「SAML 2.0 Identity Provider Metadata 」をクリック、xmlファイルとしてローカルに保存しておきます。
後ほどCognito設定時にメタデータをアップロードする時に使用します。
ユーザー追加
サイドメニュー「Users」クリック、「Add user」クリック、以下設定後「Create」クリック
Username:test_keycloak
Email:任意の値
「Credentials」タブクリック、「Set password」クリック
任意のパスワード設定、Temporary:Offで「Save」クリック
ユーザーに対して、ロールをマッピングしていきます。
サイドメニュー「Users」クリック、「Role mapping」タブクリック、「Assign role」クリック
先ほど作成したロール「Test-role」を選択し、「Assign」クリック
keycloakの設定は以上です(長いですね。。。)
再度Cognito設定をしていきます。
アプリケーションクライアントの設定
先ほど作成したユーザープールを選択してください。
IdPの設定を行なっていきます。
「サインインエクスペリエンス」タブクリック、「アイデンティティプロバイダーを追加」クリック
「SAML」チェック
メタデータドキュメントをアップロードで先ほどKeycloakでローカルに保存したxmlファイルをアップロード
SAML属性:email
「アプリケーションの統合」タブクリック、作成したアプリケーションクライアントクリック
許可されているコールバックURL:https://jwt.io
IDプロバイダーに先ほど作成したIDプロバイダーを追加、保存
OAuth2.0許可タイプは今回「暗黙的な付与」にしています。
本来は「認可コード付与」を選択するのですが、リダイレクトされたhttps://jwt.io でアクセストークンの確認をしたいので設定しています。
動作確認
AWSマネコン > Amazon Cognito > ユーザープール > アプリケーションの統合 > ホストされたUIで「ホストされたUIを表示」クリック
keycloakのログイン画面に飛びます。emailとPasswordを入力
ログインが成功すれば、許可されているコールバックURL:https://jwt.io で設定した画面に飛びます。
今回リダイレクトする際に、アクセストークンが付与されます。jwt.ioのサイトでは、渡ってきたアクセストークン(jwt)をパースして表示してくれます。
最後に
AWS CognitoとKeycloakを組み合わせて、SAMLベースのSSOを簡単に実装することができます。 初めてSSO連携を取り込む方はローカルで確認できるのでぜひやってみてください。