Amazon Cognito と Azure Entra ID (Azure AD) で AWS Amplify を使用した認証

Amazon Cognito と Azure Entra ID (Azure AD) で AWS Amplify を使用した認証

岩佐 孝浩
岩佐 孝浩
9 min read
Cognito Entra ID 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 IDCognito domain prefix を確認してください。

SAML 設定を編集してください。

以下の表に従って Entity IDReply URL を追加してください。 これらの値の詳細については、公式ドキュメントをご参照ください。

KeyValue
Entity IDurn:amazon:cognito:sp:<your user pool ID>
Reply URLhttps://<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 を実装したい場合、次の投稿もご参考いただければと思います。

この投稿が、お役に立てば幸いです。

岩佐 孝浩

岩佐 孝浩

Software Developer at KAKEHASHI Inc.
AWS を活用したクラウドネイティブ・アプリケーションの要件定義・設計・開発に従事。 株式会社カケハシで、処方箋データ収集の新たな基盤の構築に携わっています。 Japan AWS Top Engineers 2020-2023