AWS Amplify、Amazon Cognito、Azure Entra ID (Azure AD) を利用した認証機能の実装

AWS Amplify、Amazon Cognito、Azure Entra ID (Azure AD) を利用した認証機能の実装

岩佐 孝浩
岩佐 孝浩
10 min read
Cognito Entra ID Amplify

はじめに

Amazon Cognito ユーザープールは、SAML ベースの ID プロバイダーをサポートしており、企業の ID システムとシームレスな統合が可能です。この投稿では、AWS Amplify、Amazon Cognito、および Azure Entra ID を使用した認証設定の手順を説明します。

概要

認証ワークフローでは、Cognito を Azure Entra ID と SAML 経由で統合します。以下の図は、公式ドキュメントに掲載されているプロセスを視覚化したものです。

クラウドリソース

Azure Entra ID の作成

Azure Entra ID を Amazon Cognito と統合するには、次の手順で設定を行います。

1. Microsoft Entra ID に移動

Azure ポータルを開き、Microsoft Entra ID セクションに移動します。

2. エンタープライズアプリケーションの追加

メニューから Add > Enterprise application を選択します。

3. カスタムアプリケーションの作成

Create your own application を選択し、my-cognito-app などの名前を入力します。Integrate any other application you don't find in the gallery (Non-gallery) オプションを選択します。

4. シングルサインオン (SSO) の設定

Set up single sign on セクションに移動し、SAML を選択します。

メタデータ URL をコピー:

SAML 設定ページが表示されたら、metadata URL を見つけてコピーします。この URL は Cognito 設定で使用します。

Amazon Cognito ユーザープールの作成

Amazon Cognito を Azure Entra ID と統合するには、Cognito ユーザープールを作成する必要があります。以下の CloudFormation テンプレート (cognito.yaml) を使用して定義できます。

CloudFormation テンプレート

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

主なポイント

  • 属性マッピング (33-35 行目): 属性マッピングの URL は、Azure Entra ID から取得したメタデータ URL に記載されています。
  • OAuth スコープ (51 行目): aws.cognito.signin.user.admin スコープは、Amplify を使用してフロントエンドアプリケーションからユーザー情報を取得するために必要です。

SAML 2.0 リクエストとレスポンスの詳細は 公式ドキュメント をご参照ください。また、Cognito のリソースサーバーとスコープについては AWS ドキュメント をご参照ください。

CloudFormation スタックのデプロイ

<SAML_METADATA_URL> をコピーしたメタデータ 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>'

このコマンドは、Azure Entra ID を使用した SAML ベース認証に対応する Cognito ユーザープールをデプロイします。

デプロイが成功したら、Entra ID の SAML 設定を構成し、アプリケーションにユーザーを割り当てる手順に進みます。

Entra ID の SAML 設定を更新する

Azure Entra ID を Amazon Cognito と連携させるには、SAML 設定を以下のように更新します。

1. Cognito の詳細を取得

Amazon Cognito 管理コンソールで User pool IDCognito ドメインプレフィックス を確認します。

2. SAML 設定を編集

Azure Entra ID の SAML settings を開き、編集を開始します。

3. Entity ID と Reply URL を追加

以下の値を SAML 設定に使用します。詳細については 公式ドキュメント をご参照ください。

キー
Entity IDurn:amazon:cognito:sp:<your user pool ID>
Reply URLhttps://<yourDomainPrefix>.auth.<region>.amazoncognito.com/saml2/idpresponse

4. 属性とクレームの設定

Attributes and claims を編集し、アプリケーションの要件に合わせて調整します。

5. グループクレームを追加

Add a group claim をクリックし、Groups assigned to the application を選択します。

ユーザーの作成

統合をテストするために、Azure Entra ID で新しいユーザーを作成します。

1. ユーザーセクションを開く

Azure ポータルで New user をクリックします。

2. ユーザー情報を入力

必要なフィールド (例: ユーザー名や名前) を入力します。

3. メールアドレスを追加

ユーザーのメールアドレスを指定します。

4. 割り当てをスキップ

Assignments タブは一旦スキップします。

5. ユーザー作成を完了

プロセスを完了してユーザーを作成します。

アプリケーションへのユーザー割り当て

ユーザーが作成されたら、それをアプリケーションに割り当てます。

1. アプリケーションに移動

my-cognito-app エンタープライズアプリケーションを選択します。

2. ユーザーとグループを割り当て

Assign users and groups をクリックします。

3. ユーザー/グループを追加

Add user/group を選択し、作成したユーザーを選びます。

React アプリ

アプリケーションの作成

この投稿では Next.js を使用してフロントエンドアプリケーションを作成します。次のコマンドとオプションでアプリケーションを生成します:

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.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

メインページの更新

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/ を開きます。サインインページ にリダイレクトされます。

サインイン後、アプリでユーザー属性が表示されます。

Cognito 管理コンソールでユーザーが作成されたことを確認します。

クリーンアップ

AWS リソース

以下のコマンドを使用して、プロビジョニングされた AWS リソースを削除します。

aws cloudformation delete-stack --stack-name amplify-with-cognito-and-entra-id

Azure リソース

エンタープライズアプリケーションや作成したユーザーを手動で削除します。

まとめ

Amazon Cognito と Azure Entra ID の統合は、特に Active Directory を利用する企業にとって、集中管理型のアイデンティティ管理を実現する重要なステップとなります。この統合により、既存の組織ユーザーディレクトリを活用しながら、シームレスかつ安全な認証ワークフローを構築できます。

この投稿では、AWS と Azure を使用したバックエンド設定から、AWS Amplify を使用したフロントエンド実装まで、統合プロセスを段階的に解説しました。

Cognito ユーザープールを使用した Slack でのサインイン の実装に興味がある場合は、以下の関連投稿をご覧ください。

この記事がお役に立てば幸いです。

Happy Coding! 🚀

岩佐 孝浩

岩佐 孝浩

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