Amazon CognitoとADFSをSAML連携して、WEBサイトの認証処理として利用する

CognitoとADFSをSAML連携して、ActiveDirectory側のユーザー情報で認証処理をさせよう、というものです。下記あたりのドキュメントを読みながら、必要手順を確認しました。

Amazon Cognito ユーザープールを使用して AD FS を SAML ID プロバイダーとして設定するにはどうしたらよいですか?

Amazon Cognito ユーザープールのフェデレーションと連携するように Amazon EC2 Windows インスタンスに AD FS を設定するにはどうすればよいですか?

構成

AWS上の構成です。

f:id:goodbyegangster:20210107180745p:plain

環境情報

作成済の環境

以下は作成済として作業を進めます。

下記で記述あるURLの情報。Route53でレコード作成しています。

  • adfs.goodbyegangster.com
    • ADFSで利用
  • www.goodbyegangster.com
    • Web Serverで利用
  • auth2.goodbyegangster.com

Amazon Cognitoへの設定

今回の構成では、Cognitoは、IdPであるADFSのService Providerとして働きます。必要手順を確認していきます。また、ALBからCognito認証処理を呼び出す形となるので、下記の内容も確認しています。

Amazon Cognito を使用する準備を整える

User Poolの作成

User Poolを作成します。運用開始後には、SAML連携されたActiveDirectory内ユーザー情報が、このUser Poolに格納されていきます。

$ aws cognito-idp create-user-pool \
--pool-name sample-pool \
--schema \
    Name=email,Required=true \
--profile xxx

cognito-idp create-user-pool

作成されたuser-pool-idを、この先利用していくのでメモしておきます。

SAML IdPの登録

ADFSをSAML IdPとして登録し、一緒に属性マッピングを設定します。下記コマンドでは、URLを指定してSAMLメタデータの渡していますが、ADFS側で自己署名証明書を利用している場合、証明書のエラーとなり登録できません。自己署名証明書を利用している場合、AWSコンソールから登録してしまいます。

$ aws cognito-idp create-identity-provider \
--user-pool-id ap-northeast-1_lNcPCz2YH \
--provider-name=adfs \
--provider-type SAML \
--provider-details MetadataURL=https://adfs.goodbyegangster.com/federationmetadata/2007-06/federationmetadata.xml \
--attribute-mapping email=http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress \
--profile xxx

cognito-idp create-identity-provider

User PoolにApp Clientの作成

App Clientを作成します。今回の構成では、このApp ClientをALBにて利用する事になります。

$ aws cognito-idp create-user-pool-client \
--user-pool-id ap-northeast-1_lNcPCz2YH \
--client-name sample-client \
--generate-secret \
--refresh-token-validity 60 \
--token-validity-units RefreshToken=minutes \
--prevent-user-existence-errors ENABLED \
--supported-identity-providers adfs \
--callback-urls "https://www.goodbyegangster.com/oauth2/idpresponse" \
--logout-urls "https://auth.goodbyegangster.com/saml2/logout" \
--allowed-o-auth-flows "code" "implicit" \
--allowed-o-auth-scopes "email" "openid" \
--allowed-o-auth-flows-user-pool-client \
--profile xxx

cognito-idp create-user-pool-client

カスタムドメインの作成

Cognitoで利用するドメインをカスタムドメインにしておきます。前提条件があるので、確認し、必要に応じて設定しておきます。

Using Your Own Domain for the Hosted UI

僕が躓いたのは、このあたりでした。

A web domain that you own. Its root must have a valid A record in DNS. For more information see Domain Names.

root とありますが、利用するサブドメインの1階層上のドメインにAレコードを設定します。今回の例では、 auth.goodbyegangster.com をカスタムドメインとしたいので、 goodbyegangster.com に適当な値でAレコードを設定しました。

A Secure Sockets Layer (SSL) certificate managed by ACM.

You must change the AWS region to US East (N. Virginia) in the ACM console before you request or import a certificate.

利用するカスタムドメインで、ACM発行の証明書を利用できます。ACMの設定するリージョンは US East (N. Virginia) 指定です。

カスタムドメイン作成コマンドを実行。

$ aws cognito-idp create-user-pool-domain \
--user-pool-id ap-northeast-1_lNcPCz2YH \
--domain auth.goodbyegangster.com \
--custom-domain-config CertificateArn=arn:aws:acm:us-east-1:123456789012:certificate/6cb1bc42-0000-0000-0000-000000000000 \
--profile xxx
{
    "CloudFrontDomain": "d1r3fcmyahd8h6.cloudfront.net"
}

cognito-idp create-user-pool-domain

発行されたURLを利用して、Route53のホストゾーンに、エイリアスレコード登録しておきます。

ADFS側の設定

ADFS側の設定を実施します。該当のWindowsサーバーに、ドメインAdmin権限でログインします。

証明書利用者信頼(Relying Party Trust)の作成

Cognitoを、信頼されたService Providerとして登録します。

Windows管理ツール から ADFSの管理 を起動させ、 操作証明書利用者信頼の追加 をクリックします。

f:id:goodbyegangster:20210107180612p:plain

要求に対応する を選択します。

f:id:goodbyegangster:20210107180616p:plain

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

f:id:goodbyegangster:20210107180621p:plain

適当な表示名を設定。Cognito用なので、今回はCognito。

f:id:goodbyegangster:20210107180625p:plain

次へ。

f:id:goodbyegangster:20210107180629p:plain

SAML 2.0 WebSSO プロトコルのサポートを有効にする を選択し、URLに https://(Cognitoで利用するドメイン名)/saml2/idpresponse を入れます。

f:id:goodbyegangster:20210107180633p:plain

利用者信頼の識別子として、CognitoのUser Pool Id情報を右記のフォーマット urn:amazon:cognito:sp:(user-pool-id) に沿って入力します。

f:id:goodbyegangster:20210107180638p:plain

すべてのユーザーを許可。

f:id:goodbyegangster:20210107180642p:plain

証明書利用者信頼が登録されます。

f:id:goodbyegangster:20210107180647p:plain

要求発行ポリシー(Claim Rules)の編集

要求発行ポリシーを設定。今回はName IDとEmail情報を設定します。

まずNameID情報を登録します。 要求発行ポリシーの編集 をクリックします。

f:id:goodbyegangster:20210107180703p:plain

規則の追加 を選択します。

f:id:goodbyegangster:20210107180708p:plain

入力方向の要求を変換 を選択して次へ。

f:id:goodbyegangster:20210107180712p:plain

以下を登録します。

パラメーター
要求規則名 NameID
入力方向の要求の種類 Windows アカウント名
出力方向の要求の種類 名前 ID
出力方向の名前IDの形式 永続 ID
チェック すべての要求値をパススルーする

f:id:goodbyegangster:20210107180717p:plain

登録できました。続いてEmail情報を登録するため、再度 規則の追加 をクリック。

f:id:goodbyegangster:20210107180721p:plain

LDAP属性を要求として送信 を選択して次へ。

f:id:goodbyegangster:20210107180725p:plain

以下を登録します。

パラメーター
要求規則名 Email
属性ストア Active Directory
LDAP属性 E-Mail-Addresses
出力方向の要求の種類 電子メールアドレス

f:id:goodbyegangster:20210107180729p:plain

登録できました。

f:id:goodbyegangster:20210107180734p:plain

ADFS側の設定は完了です。

ALBの設定

ALBに、Cognito認証処理を実施するよう設定します。一般的なALB設定手順は割愛して、Cognito情報を登録することになるリスナールール部分のみ貼り付けます。

パラメーター
Authenticate Amazon Congnito
Cognito user pool 上記で作成したもの
App Client 上記で作成したもの
Session cookie name (デフォルト)
Session timeout (デフォルト)
Scope openid
Action on unauthenticated request Authenticate

f:id:goodbyegangster:20210117001543j:plain

下記ドキュメントを確認しています。

ユーザー認証を設定する

接続確認

必要設定は完了したので、実際にWEBサイトにアクセスしてみます。WEBサイトにアクセスすると、ADFS提供のサインインページにリダイレクトされます。今回は自己署名証明書を利用しているため、ブラウザに警告メッセージが表示されています。

f:id:goodbyegangster:20210107180651p:plain

ActiveDirectoryに登録されているユーザー情報にてサインイン。

f:id:goodbyegangster:20210107180655p:plain

サインインすると、実際のWEBページ(Nginxのデフォルトページ)にリダイレクトされます。

f:id:goodbyegangster:20210107180700p:plain


今回は確認しませんでしたが、認証ログアウトの動作は、ALB側のセッション・クッキーのタイムアウト値(デフォルトでは604800秒)と、Cognito側の各種トークンの有効期限が関係するとのこと。

認証のログアウトとセッションのタイムアウト