Amazon Cognito と Azure Entra ID (Azure AD) で AWS Amplify を使用した認証
Amazon Cognito user pools は、公式ドキュメントで説明されているように、 SAML ベースの IdP をサポートしています。
この投稿では、 AWS Amplify を使用して Amazon Cognito および Azure Entra ID で認証する手順を説明します。
概要
以下の図は、公式ドキュメントから引用しています。
クラウドのリソース
Azure Entra ID 作成
以下のステップに従って、 Entra ID を作成してください。
Microsoft Entra ID
に移動してください。
Add > Enterprise application
をクリックしてください。
Create your own application
をクリックしてください。
my-cognito-app
をアプリケーション名として入力し、 Integrate any other application you don't find in the gallery (Non-gallery)
を選択後、アプリケーションの作成を完了してください。
Set up single sign on
に移動してください。
SAML
を選択してください。
Metadata URL をコピーしてください。
Amazon Cognito User Pool 作成
Cognito user pool を作成するため、下記の内容を含む cognito.yaml
CloudFormation テンプレートを作成してください。
属性マッピングの URL (33-35行目) は、メタデータの URL から見つけることができます。 Entra ID がサポートする SAML 2.0 のリクエストおよびレスポンスの詳細については、公式ドキュメントをご参照ください。
aws.cognito.signin.user.admin
スコープ (51行目) は、 Amplify を使用してフロントエンドからユーザー情報をクエリするために必要です。
詳細については、公式ドキュメントをご参照ください。
AWSTemplateFormatVersion: 2010-09-09
Description: Cognito user pool federated with Azure Entra ID
Parameters:
Domain:
Type: String
Description: Cognito user pool domain
CallbackURLs:
Type: CommaDelimitedList
Default: 'http://localhost:3000/'
LogoutURLs:
Type: CommaDelimitedList
Default: 'http://localhost:3000/'
MetadataURL:
Type: String
Description: SAML metadata url of your Azure Entra ID
Resources:
CognitoUserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: cognito-federated-with-azure-entra-id
CognitoUserPoolDomain:
Type: AWS::Cognito::UserPoolDomain
Properties:
Domain: !Ref Domain
UserPoolId: !Ref CognitoUserPool
CognitoUserPoolIdentityProvider:
Type: AWS::Cognito::UserPoolIdentityProvider
Properties:
AttributeMapping:
email: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress'
name: 'http://schemas.microsoft.com/identity/claims/displayname'
ProviderDetails:
IDPSignout: true
MetadataURL: !Ref MetadataURL
ProviderName: azure-entra-id
ProviderType: SAML
UserPoolId: !Ref CognitoUserPool
CognitoUserPoolClient:
Type: AWS::Cognito::UserPoolClient
Properties:
AllowedOAuthFlows:
- code
AllowedOAuthScopes:
- email
- openid
- aws.cognito.signin.user.admin
AllowedOAuthFlowsUserPoolClient: true
CallbackURLs: !Ref CallbackURLs
LogoutURLs: !Ref LogoutURLs
ClientName: public client
SupportedIdentityProviders:
- COGNITO
- !Ref CognitoUserPoolIdentityProvider
UserPoolId: !Ref CognitoUserPool
以下のコマンドを実行して CloudFormation スタックをデプロイしてください。
実行前に、 <SAML_METADATA_URL>
を、上でコピーした実際の値に置き換えてください。
aws cloudformation deploy \
--template-file cognito.yaml \
--stack-name amplify-with-cognito-and-entra-id \
--parameter-overrides Domain=$(uuidgen | tr "[:upper:]" "[:lower:]") MetadataURL='<SAML_METADATA_URL>'
Entra ID SAML 設定更新
Cognito マネジメントコンソールで User pool ID
と Cognito domain prefix
を確認してください。
SAML 設定を編集してください。
以下の表に従って Entity ID
と Reply URL
を追加してください。
これらの値の詳細については、公式ドキュメントをご参照ください。
Key | Value |
---|---|
Entity ID | urn:amazon:cognito:sp:<your user pool ID> |
Reply URL | https://<yourDomainPrefix>.auth.<region>.amazoncognito.com/saml2/idpresponse |
属性とクレームを編集してください。
Add a group claim
をクリックしてください。
Groups assigned to the application
を選択してください。
ユーザー作成
以下のステップに従って、 Entra ID にユーザーを作成してください。
New user
をクリックしてください。
任意の値を入力してください。
メールアドレスを入力してください。
Assignments
タブはスキップしてください。
ユーザーの作成を完了してください。
ユーザー割り当て
Enterprise application で my-cognito-app
を選択してください。
Assign users and groups
を選択してください。
Add user/group
を選択してください。
割り当てるユーザーを選択してください。
React App
App 作成
フロントエンドアプリを作成するために、この投稿では Next.js を使用しています。
以下のオプションで npx create-next-app@latest
を使用してアプリを作成してください。
npx create-next-app@latest
✔ What is your project named? … amplify-with-cognito-and-entra-id
✔ Would you like to use TypeScript? … Yes
✔ Would you like to use ESLint? … Yes
✔ Would you like to use Tailwind CSS? … Yes
✔ Would you like to use `src/` directory? … Yes
✔ Would you like to use App Router? (recommended) … Yes
✔ Would you like to customize the default import alias (@/*)? … Yes
✔ What import alias would you like configured? … @/*
作業ディレクトリをプロジェクトのルートに変更し、以下のコマンドで AWS Amplify をインストールしてください。
cd amplify-with-cognito-and-entra-id
npm i aws-amplify
Env ファイル作成
以下の内容で .env.local
を作成してください。
必ず以下のプレースホルダを、実際の値で置き換えてください。
<USER_POOL_ID>
<USER_POOL_CLIENT_ID>
<DOMAIN_PREFIX>
NEXT_PUBLIC_USER_POOL_ID=<USER_POOL_ID>
NEXT_PUBLIC_USER_POOL_CLIENT_ID=<USER_POOL_CLIENT_ID>
NEXT_PUBLIC_USER_POOL_ID_PROVIDER=azure-entra-id
NEXT_PUBLIC_OAUTH_DOMAIN=<DOMAIN_PREFIX>.auth.ap-northeast-1.amazoncognito.com
Page 更新
src/app/page.tsx
を以下の内容で更新してください。
'use client'
import { useEffect, useState } from 'react';
import { Amplify } from 'aws-amplify';
import { FetchUserAttributesOutput, fetchUserAttributes, getCurrentUser, signInWithRedirect, signOut } from 'aws-amplify/auth';
Amplify.configure({
Auth: {
Cognito: {
userPoolId: process.env.NEXT_PUBLIC_USER_POOL_ID as string,
userPoolClientId: process.env.NEXT_PUBLIC_USER_POOL_CLIENT_ID as string,
loginWith: {
oauth: {
domain: process.env.NEXT_PUBLIC_OAUTH_DOMAIN as string,
scopes: [
'email',
'openid',
'aws.cognito.signin.user.admin',
],
redirectSignIn: ['http://localhost:3000/'],
redirectSignOut: ['http://localhost:3000/'],
responseType: 'code',
},
},
},
},
});
export default function Home() {
const [attributes, setAttributes] = useState<FetchUserAttributesOutput>();
useEffect(() => {
(async () => {
try {
await getCurrentUser();
const attributes = await fetchUserAttributes();
setAttributes(attributes);
} catch (error) {
await signInWithRedirect({ provider: { custom: process.env.NEXT_PUBLIC_USER_POOL_ID_PROVIDER as string } });
}
})();
}, []);
return (
<div className='flex flex-col gap-2 max-w-sm mx-auto my-4'>
<div className='flex gap-2'>
<div>Sub:</div>
<div>{attributes?.sub}</div>
</div>
<div className='flex gap-2'>
<div>Name:</div>
<div>{attributes?.name}</div>
</div>
<div className='flex gap-2'>
<div>Email:</div>
<div>{attributes?.email}</div>
</div>
<button
type="button"
className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800"
onClick={() => signOut()}
>
Sign out
</button>
</div>
);
}
動作確認
npm run dev
を実行して開発サーバーを起動し、ブラウザで http://localhost:3000/
を開いてください。
サインインページにリダイレクトされます。
React アプリで、ユーザーの属性を確認できます。
Cognito マネジメントコンソールでもユーザーを確認できます。
クリーンアップ
AWS
以下のコマンドを使用して、プロビジョニングされた AWS リソースを削除してください。
aws cloudformation delete-stack --stack-name amplify-with-cognito-and-entra-id
Azure
Enterprise application と作成したユーザーを、手動で削除してください。
まとめ
多くの企業、特に大企業で、 Active Directory を利用しているケースが多いため、 Cognito と Entra ID の連携が要件になることが少なからずあります。 少し設定が必要ですが、この投稿でご紹介したとおり、連携は容易に可能です。
Cognito User Pools を利用した Sign in with Slack を実装したい場合、次の投稿もご参考いただければと思います。
この投稿が、お役に立てば幸いです。