ADFSをSAML IdPとしてCognitoユーザープールと連携する

2021.02.28

Amazon Cognitoは、外部IdPと連携してサインインすることができるのでSAML IdPとCognitoユーザープールを連携する環境を用意してみました。

構成概要

今回はパブリックサブネットのEC2インスタンスにActiveDirectoryとADFSをインストールします。AWS DirectoryServiceだと最低2つのドメインコントローラーを自動的に用意されること、ADFS用のEC2インスタンスが必要であることから費用が高くなるのでEC2インスタンスで作っていきます。また、スポットインスタンスだと安価で利用できるのでスポットリクエストします。 Cognitoからリダイレクトされる際にADFSサーバが名前解決できる必要がある為、ドメインを取得します。Route53でドメインを購入しても良いですが、無料ドメインを取得される方は、以下を参考にしてください。ADFSサーバとして利用するElastic IPを一つ取得し、Route53のHosted ZoneにAレコードad1.無料ドメインとして登録します。

セキュリティグループでは、自身のIPアドレスを送信元としてtcp/80tcp/443を許可します。自分だけが利用する環境なので送信元のIPアドレスを限定しています。

EC2インスタンス起動

EC2インスタンスはAWS CLIで起動します。2021/2/27時点で最新のWindowsAMI(Windows_Server-2019-Japanese-Full-Base-2021.02.10)をスポットインスタンスで起動するのでスポットリクエスト用のjsonファイル(spot-options.json)を作成します。MaxPriceは、こちらを参考に下回らない価格で設定してください。(2021/2/27時点のt3.mediumは$0.0347)ホスト名、タイムゾーン、ADおよびADFSのインストールを実行するUserDataファイル(userdata.txt)を作成しておきます。

#スポットリクエストファイル

% cat ./spot-options.json 
{
  "MarketType": "spot",
  "SpotOptions": {
    "MaxPrice": "0.035",
    "SpotInstanceType": "persistent",
    "InstanceInterruptionBehavior": "stop"
  }
}

#初期設定、ADおよびADFSインストール
% cat ./userdata.txt
<powershell>
Rename-Computer -NewName ad1 -Force
Set-TimeZone -Id "Tokyo Standard Time"
Start-Sleep -s 5
Install-WindowsFeature -Name ADFS-Federation
Install-WindowsFeature -Name Web-Server
Install-WindowsFeature -Name Web-Mgmt-Console
Install-WindowsFeature -Name AD-Domain-Services
Install-WindowsFeature -Name RSAT-ADDS
Restart-Computer -Force
</powershell>

# スポットインスタンス起動 ※パブリックサブネットを指定すること
% aws ec2 run-instances \
--image-id ami-04e7189e8e1f2f4ac \
--instance-type t3.medium \
--count 1 \
--subnet-id subnet-xxxxxxxxxxxxxxxxx \
--key-name キーペア指定 -\
-security-group-ids sg-xxxxxxxxxxxxxxxxx \
--credit-specification CpuCredits=standard \
--instance-market-options file://spot-options.json \
--user-data file://userdata.txt
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=ad-and-adfs}]' 'ResourceType=volume,Tags=[{Key=Name,Value=ad-and-adfs}]'

# Elastic IP割当
% aws ec2 associate-address --allocation-id 取得済みElasticIPのID --instance インスタンスID

ADおよびADFS設定

AD設定

EC2インスタンスにRDPして進めていきます。まずはADから設定していきます。サーバマネージャの通知をクリックして「このサーバーをドメインコントローラーに昇格する」をクリックします。

「新しいフォレストを追加する」を選択してルートドメインを入力します。

DSRMのパスワードを入力します。

DNSオプションはそのまま進めて検証できるので次に進みます。

NetBIOSドメイン名は自動で入力される為、次に進みます。

パス、オプションの確認はデフォルトで進めます。前提条件のチェックが完了したらインストールします。

インストールが完了すると再起動されるので再度RDPします。サーバーマネージャのローカルサーバでドメインがルートドメイン名になっていればAD設定は、完了です。

IIS設定(自己証明書、サイトバインディング)

ADFSで利用する自己証明書をIISで作成します。ツールからIISマネージャを開いて「サーバ証明書」をダブルクリックします。

備考にある「自己署名入り証明書の作成」をクリックします。

Route53に登録したAレコードと同じ値で証明書を作成します。

IISのDefault Web Siteを右クリックして「バインドの編集」をクリックします。

サイトバインドの追加からhttpsでad1.無料ドメインをホスト名、SSL証明書を自己証明書を設定します。

ADFSインストール

今度はADFSを設定していきます。通知から「このサーバーにフェデレーションサービスを構成します」をクリックします。

新規のADFSを作成するのでオプションはデフォルトのままとします。

ドメイン管理者権限を持つユーザーとしてデフォルトで指定されているAdministratorで進めます。

サービスのプロパティでIISで作成した自己証明書を選択します。

サービスアカウントとしてAdministratorを選択してパスワードを入力します。RDPで接続するときのパスワードです。

データベースの指定、オプションはデフォルトで進めて「構成」をクリックします。ここでインストールは完了ですが、Cognitoユーザープール作成後、証明書利用者の信頼およびクレームの追加設定をします。

Cognitoユーザープールの作成

任意のユーザープール名を入力し、「ステップに従って設定」をクリックします。

電子メールのサインインを許可したいので「検証済みのEメールアドレスでのサインインも許可」をチェックします。

「アプリクライアントの追加」から任意のアプリクライアント名の入力、クライアントシークレットのチェックを外して追加します。

アプリクライアントが追加できたらCognitoドメインを作成します。Hosted UIを使ってIdP認証フローが開始されます。

SAML ユーザープールの IdP 認証フロー

SAML IdPの設定は後ほど。

ADFS 証明書利用者の信頼およびクレームの追加

再びADFSに戻ります。管理ツールで「AD FSの管理」を開きます。

証明書利用者信頼から証明書利用者信頼の追加をクリックします。

「証明書利用者についてのデータを手動で入力する」を選択します。

任意の表示名を入力します。

「SAML 2.0 WebSSO プロトコルのサポートを有効にする」にチェックを入れて証明書利用者SAML 2.0 SSOサービスのURLにCognitoユーザープールの作成時に作ったCognitoドメインを指定したエンドポイント(https://Cognitoドメイン.auth.ap-northeast-1.amazoncognito.com/saml2/idpresponse)を入力します。

証明書利用者信頼の識別子(urn:amazon:cognito:sp:ユーザープールID)を追加します。

すべてのユーザーを許可するを選択します。後はそのまま進めて作成します。

SAMLアサーションを仲介する為の要求規則(クレームルール)を作成します。「規則の追加」をクリックします。

Cognitoユーザープールでは、email属性を必須としているので以下の内容で作成します。

次にアサーションリクエストのNameIDPolicyの変換規則を設定します。ユーザープールに作成されるフェデレーションユーザーを一意に識別するための設定です。以下の設定にするとユーザープールに「idpname_user@ドメイン」ユーザーが作成されます。

メタデータの取得とSAML IdP設定

メタデータURL(https://ad1.無料ドメイン/federationmetadata/2007-06/federationmetadata.xml)にアクセスし、メタデータを取得します。

CognitoユーザープールでIDプロバイダからSAMLを選択し、メタデータファイルのアップロードし、任意のプロバイダ名を入力し、プロバイダを作成します。

ユーザープールの属性emalとSAML属性(https://docs.microsoft.com/ja-jp/windows-server/identity/ad-fs/technical-reference/the-role-of-claims)をマッピングします。

アプリクライアントの設定で作成したSAML IdPを有効なIDプロバイダとしてチェックします。コールバックURLはSAML認証後にアクセスするURLを入力します。OAuth2.0では、Implicit grantemailopenid、をチェックします。

以上でADFSとCognitoユーザープールの設定は完了です。

テストユーザー作成

サーバーマネージャで「Active Directory ユーザーコンピューター」をクリックします。

Usersにテストユーザーを作成します。

テストユーザーを右クリックでプロパティを開いてAdministratorsグループの追加、電子メールを設定します。

Cognito Hosted UIにアクセスします。

https://Cognitoドメイン.auth.ap-northeast-1.amazoncognito.com/login?client_id=アプリクライアントID&response_type=code&scope=aws.cognito.signin.user.admin+email+openid+phone+profile&redirect_uri=コールバックURL

以下の画面が表示されたらプロバイダ名をクリックするとADFSにリダイレクトされます。

テストユーザーのメールアドレス、パスワードを入力し、サインインしてコールバックURLにリダイレクトされたら成功です。

おわりに

今までADやらSAMLやら認証基盤を設計構築する機会がほとんどなく、構築するのにとても手間取りましたが理解を深めることができました。とは言っても認証認可は奥が深いので「やってみた」を続けながらさらに理解を深めていきたいと思います。