13
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OktaとAWS Cognito連携 ・SAML編(2025年7月最新版)

13
Last updated at Posted at 2023-03-12

はじめに

CognitoとOktaをSAML連携する方法を、ハンズオン形式で紹介しています。

もともとは2023年に書いた記事ですが、2025年7月時点での最新の画面や仕様に合わせてリライトしました。

完成イメージ

次の2つを実装していきます。

  1. ログインすると https://jwt.io/ja に飛ぶ。Cognitoのアクセストークンを確認する
  2. ローカルで立ち上げたReactアプリにログインする

次のようなイメージです。

  • ログインすると jwt.io に飛ぶ。Cognitoのアクセストークンを確認する

一旦、CognitoのOkta連携を確認するための実装です。

login.png

スクリーンショット 2025-07-11 9.55.45.png

  • ローカルで立ち上げたReactアプリにログインする

「Sign in」すると自分のアクセストークンが画面に表示されるだけのアプリです。

スクリーンショット 2025-07-11 16.17.45.png

login.png

スクリーンショット 2025-07-11 16.18.05.png

:tv: 動画版ハンズオン

動画版ハンズオンも作成しています!

「とりあえず作業を眺めたい」「動画で確認しながら手を動かしたい」と言う方は是非見てみて下さい:pray:

前提

  • Node.js(私の環境ではv22.14.0)
  • AWSのアカウント
  • Oktaのアカウント

Oktaのアカウントが無い人は下記で登録して下さい。この記事では「BEST FOR DEVELOPERS」と書かれたプランを使っています。

手順

  1. Cognito・ユーザープール作成
  2. Okta・新しいアプリ統合を作成
  3. CognitoをOktaとSAML連携(アイデンティティプロバイダー追加)
  4. ログインできるかテスト
  5. ユーザー名をトークンに入れる(Lambdaトリガー)
  6. OAuth付与タイプを変更
  7. Reactにログイン機能を実装

1. Cognito・ユーザープール作成

ユーザープールを作成

Cognitoに移動して「ユーザープールを作成」します。

スクリーンショット 2025-07-11 9.16.04.png

項目名
アプリケーションタイプ シングルページアプリケーション(SPA)
アプリケーションに名前を付ける My SPA app
サインイン識別子のオプション メールアドレス
サインアップのための必須属性 email

上記のように設定して「ユーザーディレクトリを作成する」をクリックします。

スクリーンショット 2025-07-11 9.18.02.png

↓のページで特に何も設定しません。下部へスクロールします。

スクリーンショット 2025-07-11 9.20.33.png

「概要に移動」します。

スクリーンショット 2025-07-11 9.20.54.png

✅ ユーザープールの作成ができました!

ユーザープール名を変更

「概要」メニューにて「名前変更」します。

スクリーンショット 2025-07-11 9.21.24.png

項目名
ユーザープール名 User pool with Okta

上記のように設定します(※ユーザープール名は別に好きなものを付けて大丈夫です)。

スクリーンショット 2025-07-11 9.21.39.png

✅「1. Cognito・ユーザープール作成」は完了です!

2. Okta・新しいアプリ統合を作成

OktaのAdmin Consoleにて「アプリケーション」→「アプリケーション」へ移動します。

アプリ統合を作成

「アプリ統合を作成」をします。

スクリーンショット 2025-07-11 9.24.58.png

「SAML 2.0」を選択して「次へ」移動します。

スクリーンショット 2025-07-11 9.25.05.png

アプリ名を「Cognito SAML」として「次へ」移動します。

スクリーンショット 2025-07-11 9.25.24.png

シングルサインオンURL

ユーザーがOktaでログインした後に、OktaがCognitoに対してユーザーのログイン完了を通知する先です。

自分のCognitoドメイン/saml2/idpresponse https://ap-northeast-1zpzvpl7q4.auth.ap-northeast-1.amazoncognito.com/saml2/idpresponse
自分の「Cognitoドメイン」を何処で確認できるか?

「ブランディング」→「ドメイン」にて「Cognitoドメイン」を確認できます。

スクリーンショット 2025-07-11 9.26.56.png

オーディエンスURI(SPエンティティID)

上記通知をCognitoが受け取った際に、ちゃんと自分宛のものだよね?を確認するためのものです。

urn:amazon:cognito:sp:ユーザープール ID urn:amazon:cognito:sp:ap-northeast-1_ZpzVPl7Q4
自分の「ユーザープール ID」を何処で確認できるか?

「概要」メニューにて確認できます。

スクリーンショット 2025-07-11 9.27.48.png

SAMLを構成

上記を参考に「シングルサインオンURL」と「オーディエンスURI(SPエンティティID)」を設定します。

スクリーンショット 2025-07-11 9.28.25.png

下部にスクロールします。

名前
email user.email
displayname user.displayName

「属性ステートメント」を上記のように設定します。

Oktaのユーザー情報のどの属性をCognitoに渡すかの設定です(※他にも任意の属性も渡せます)。

設定できたら「次へ」移動します。

スクリーンショット 2025-07-11 9.29.47.png

「これは当社で作成した社内アプリです」にチェックを入れて「終了」します。

スクリーンショット 2025-07-11 9.30.13.png

ユーザーに割り当て

ログインできるユーザーの割り当てをします。

「割り当て」タブで「ユーザーに割り当て」(※下図参考)を選択します。

スクリーンショット 2025-07-11 9.30.48.png

ユーザーを「割り当て」ます。

スクリーンショット 2025-07-11 9.31.17.png

「保存して戻る」をしたら「完了」します。

スクリーンショット 2025-07-11 9.31.29.png

ユーザーの属性を変更

先ほど設定したuser.displayNameを編集します(未編集の方のみ)。

割り当てたユーザーのユーザー名(例:Jiro Yoyogi)をクリックします。

スクリーンショット 2025-07-11 11.50.04.png

「プロファイル」タブに移動して「編集」します。

スクリーンショット 2025-07-11 11.50.50.png

「displayName」の項目を探してご自身の名前など任意の値を入力して下さい。

スクリーンショット 2025-07-11 11.51.34.png

IdPメタデータの取得

「サインオン」タブに移動して下部にスクロールします。

スクリーンショット 2025-07-11 9.33.40.png

「SAML署名証明書」という項目があります。ステータスがアクティブになってるものを「IdPメタデータを表示」します。

スクリーンショット 2025-07-11 9.33.20.png

XMLが表示されます。Oktaの設定情報のようなものです。この後でCognitoに渡します。

スクリーンショット 2025-07-11 9.34.51.png

DL(保存)します。

スクリーンショット 2025-07-11 9.35.10.png

✅ 以上でOktaでの設定は完了です!いよいよCognitoをOktaとSAML連携させていきます!

3. CognitoをOktaとSAML連携

AWSのマネージメントコンソールに戻ります。

アイデンティティプライバイダーを追加

「認証」→「ソーシャルプロバイダーと外部プロバイダー」→「アイデンティティプロバイダーを追加」します。

スクリーンショット 2025-07-11 9.37.21.png

「SAML」を選択します。

スクリーンショット 2025-07-11 9.38.13.png

「プロバイダー名」を「Okta」とします。その他はデフォルトのままで大丈夫です。

スクリーンショット 2025-07-11 9.38.44.png

「ファイルを選択」して先ほどDLしたXMLをアップロードします。

メタデータドキュメントのエンドポイントURLを入力とは?

メタデータドキュメント(Oktaの設定情報)を渡したい場合は2つの方法があります。1つはXMLをアップロードする方法、もう1つはXMLをDLする際に表示した画面のURLを入力する方法です。この記事ではアップロードする方法で進めます。

スクリーンショット 2025-07-11 9.39.18.png

スクリーンショット 2025-07-11 9.39.43.png

「SAMLプロバイダーとユーザープール間で属性をマッピング」を下記のように設定します。

ユーザープール属性 SAML属性
email email
name displayname

Oktaから渡ってくるemail、displaynameというユーザー属性をCognitoで受け止める設定です。ここまでできたら「アイデンティティプロバイダーを追加」します。

スクリーンショット 2025-07-11 9.54.14.png

ログイン後に飛ばすページを設定

「アプリケーションクライアント」→「My SPA app」をクリックします。

スクリーンショット 2025-07-11 9.40.49.png

「ログインページ」タブで「編集」します。

スクリーンショット 2025-07-11 9.41.25.png

項目名
許可されているコールバックURL https://jwt.io/ja

Oktaのログイン画面でログインした後に飛ばすリダイレクト先です。現時点でログインした後に飛ばすページを用意していないので、一旦、上記のURLに飛ばすように設定します。

スクリーンショット 2025-07-11 9.42.05.png

「IDプロバイダー」にて「Okta」にチェックを入れて追加します。

スクリーンショット 2025-07-11 9.42.15.png

「OAuth 2.0許可タイプ」は下図のように設定します。

❎ 認証コード付与
✅ 暗黙的な付与

上記のようにすると「許可されているコールバックURL」にリダイレクトする際に、アクセストークンがURLにクエリとして付与されるようになります。何が嬉しいかというと、ログイン後にjwt.ioにリダイレクトした際に、アクセストークンの中身をjwt.ioの画面上で確認できるようになります。視覚的にちゃんとCognitoとOktaが連携されているよねー、ということを確認しやすいかと思い、このようにしています。

あくまでSAML連携の確認のための一時的な設定です。後でまた元に戻します。

スクリーンショット 2025-07-11 9.42.33.png

ここまでできたら「変更を保存」します。

スクリーンショット 2025-07-11 9.43.01.png

✅ CognitoとOktaのSAML連携が完了しました!

4. ログインできるかテスト

右上にある「ログインページを表示」をクリックします。

スクリーンショット 2025-07-11 9.44.05.png

まずはCognitoのログイン画面に飛びます。「Continue with Okta」のボタンを押します。

スクリーンショット 2025-07-11 9.44.12.png

すると、Oktaのログイン画面に遷移しました。

スクリーンショット 2025-07-11 9.45.50.png

Oktaでログインすると、「jwt.io」にリダイレクトされます。URLにアクセストークンが付与されてることと、画面に表示されてるトークンの中身を眺めてみて下さい。ご自身のメールアドレスなどがあることを確認できるかと思います。

スクリーンショット 2025-07-11 9.55.45.png

Okta連携してCognitoに登録されたユーザーも確認しておきます。

「ユーザー管理」→「ユーザー」 します。

すると、okta_と接頭辞のあるユーザーを確認できます。

スクリーンショット 2025-07-11 9.56.09.png

ユーザーを選択すると、nameの項目でOktaユーザーのdisplayNameが渡って来ている事も確認できます。

スクリーンショット 2025-07-11 9.56.42.png

✅ これでCognitoとOktaのSAML連携の基本的な部分は完了です!

5. ユーザー名をトークンに入れる(Lambdaトリガー)

で、恐らく気になった人もいるかと思いますが、jwt.ioのページで表示されてるアクセストークンの中に「name」の項目がありません。ただ、場合によっては、nameをトークンに埋めたい要望もあるかと思います。どのようにしたら良いか?

Cognitoがアクセストークンを払い出す際に、Lambdaを挟む事ができます。このLambdaでアクセストークンに埋める値を調整することができます。

Lambdaトリガーを追加

「認証」→「拡張機能」にて「Lambdaトリガーを追加」します。

スクリーンショット 2025-07-11 9.59.55.png

項目名
トリガータイプ 認証
認証 トークン生成前トリガー
トリガーイベントバージョン 基本機能 + ユーザー ID とマシン ID のアクセストークンのカスタマイズ - 推奨

スクリーンショット 2025-07-11 10.00.20.png

「Lambda関数の作成」をします。

スクリーンショット 2025-07-11 10.00.39.png

Lambda関数を作成

Lambdaの画面に遷移したら「関数を作成」します。

スクリーンショット 2025-07-11 10.01.20.png

項目名
関数名 cognito-token-customizer
ランタイム Node.js 22.x
アーキテクチャ x86_64
実行ロール 基本的なLambdaアクセス権限で新しいロールを作成

上記のように設定していきます。

スクリーンショット 2025-07-11 10.02.12.png

「関数の作成」をします。

スクリーンショット 2025-07-11 10.03.00.png

index.mjsの中身を次のコードで置き換えます。

export const handler = async (event) => {
  // userAttributes から必要な属性をトークンに追加
  const attrs = event.request.userAttributes;

  event.response = {
    claimsAndScopeOverrideDetails: {
      idTokenGeneration: {
        claimsToAddOrOverride: {
          name: attrs.name
        },
      }
    }
  };

  return event;
};

置き換えられたら「Deploy」します。下図のように「正常に更新されました」という文言が出たら完了です。

スクリーンショット 2025-07-11 10.04.45.png

Lambda関数を選択

Cognitoに戻り、作成した「cognito-token-customizer」を選択します。

スクリーンショット 2025-07-11 10.05.07.png

「Lambdaトリガーを追加」します。

スクリーンショット 2025-07-11 10.05.25.png

✅ これでアクセストークンにnameの項目が入るようになりました。

再び「ログインページを表示」からログインを試します。

スクリーンショット 2025-07-11 10.06.03.png

すると、nameの項目が現れるようになりました!

スクリーンショット 2025-07-11 10.06.56.png

6. OAuth付与タイプを変更

ここまでで、SAML連携の確認ができました。OAuth 2.0許可タイプを「暗黙的な付与」→「認証コード付与」へと戻していきます。

URLにアクセストークンが付いてる状態は望ましくない

暗黙的な付与→認証コード付与

「アプリケーション」→「アプリケーションクライアント」→「My SPA app」→「ログインページ」タブにて「編集」します。

スクリーンショット 2025-07-11 10.08.29.png

「OAuth 2.0許可タイプ」を次のように変更します。

✅ 認証コード付与
❎ 暗黙的な付与

スクリーンショット 2025-07-11 10.08.47.png

「変更を保存」します。

スクリーンショット 2025-07-11 13.25.01.png

再度「ログインページを表示」からログインします。

スクリーンショット 2025-07-11 10.06.03.png

トークンが付いていないことを確認できます。

スクリーンショット 2025-07-11 10.10.01.png

codeとは?

簡単に言うとトークンの引換券です。キーワードで言うとPKCE認証で使うものです。アクセストークンを取得したい場合は、このcodeをCognitoに送って引き換えて貰います。

この後、Reactで簡単なログイン・ログアウトのアプリを作ります。その中で引き換えてる部分について確認します。

✅ これでよりセキュアな状態になりました。

7. Reactにログイン機能を実装

Viteプロジェクト作成

作業フォルダーに移動して下記コマンドを実行します。

npm create vite@latest

以下のように入力・選択します。

  • Project name
    • cognito-okta-app
  • Select a framework
    • React
  • Select a variant
    • TypeScript

続いてプロジェクトフォルダに移動して下記コマンドを実行します。

npm install

下記コマンドを実行して「http://localhost:5173/」でアプリが立ち上がれば成功です。

npm run dev

次のような画面が現れたら問題無くReactのプロジェクトが作れていますので、先に進めていきます。

スクリーンショット 2025-07-11 15.41.07.png

2025年7月現在のデフォルト画面です。Vite側で変更される可能性があります。

ライブラリをインストール

Cognitoでログインするためのライブラリをインストールします。

npm install oidc-client-ts react-oidc-context --save

コードの実装

変更するのは下記コードです。

  • main.tsx
  • App.tsx

main.tsx

下記2つをご自身のものに書き換えて下さい。

  • ユーザープールID
  • アプリケーションクライアントID
ユーザープールIDとアプリケーションクライアントIDの場所は?
  • ユーザープールID

スクリーンショット 2025-07-11 15.50.49.png

  • アプリケーションクライアントID

スクリーンショット 2025-07-11 15.51.10.png

// main.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { AuthProvider } from "react-oidc-context";

const cognitoAuthConfig = {
  // e.g. https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_c7NPd74MH
  authority: "https://cognito-idp.ap-northeast-1.amazonaws.com/{ユーザープール ID}",
  // e.g. 6ehuq2e03ftb5kr5dgl2ke5h0o
  client_id: "{アプリケーションクライアントID}",
  redirect_uri: "http://localhost:5173/",
  response_type: "code",
  scope: "email openid phone",
};

const root = ReactDOM.createRoot(document.getElementById("root")!);

// wrap the application with AuthProvider
root.render(
  <React.StrictMode>
    <AuthProvider {...cognitoAuthConfig}>
      <App />
    </AuthProvider>
  </React.StrictMode>
);

App.tsx

下記2つをご自身のものに書き換えて下さい。

  • アプリケーションクライアントID
  • Cognito ドメイン
Cognito ドメインの場所は?

「ブランディング」→「ドメイン」

スクリーンショット 2025-07-11 15.56.30.png

// App.tsx

import { useAuth } from "react-oidc-context";

function App() {
  const auth = useAuth();

  const signOutRedirect = () => {
    // e.g. 6ehuq2e03ftb5kr5dgl2ke5h0o
    const clientId = "{アプリケーションクライアントID}";
    const logoutUri = "http://localhost:5173/";
    // e.g. https://ap-northeast-1c7npd74mh.auth.ap-northeast-1.amazoncognito.com
    const cognitoDomain = "{Cognito ドメイン}";
    window.location.href = `${cognitoDomain}/logout?client_id=${clientId}&logout_uri=${encodeURIComponent(logoutUri)}`;
  };

  if (auth.isLoading) {
    return <div>Loading...</div>;
  }

  if (auth.error) {
    return <div>Encountering error... {auth.error.message}</div>;
  }

  if (auth.isAuthenticated) {
    return (
      <div>
        <pre> Hello: {auth.user?.profile.email} </pre>
        <pre> ID Token: {auth.user?.id_token} </pre>
        <pre> Access Token: {auth.user?.access_token} </pre>
        <pre> Refresh Token: {auth.user?.refresh_token} </pre>

        <button onClick={() => auth.removeUser()}>Sign out</button>
      </div>
    );
  }

  return (
    <div>
      <button onClick={() => auth.signinRedirect()}>Sign in</button>
      <button onClick={() => signOutRedirect()}>Sign out</button>
    </div>
  );
}

export default App;

変更は以上です。

上記コードはCognitoが用意してるQuick Setup ガイドのコード(2025年7月現在)と同じものです。

スクリーンショット 2025-07-11 16.04.47.png

画面確認

下記コマンドで再度アプリを立ち上げます。

npm run dev

すると下図のようにサインインとサインアウトのボタンだけのページが表示されます。

スクリーンショット 2025-07-11 16.02.03.png

「Sign in」してみると、今の時点では下記のようにエラー画面になります。

スクリーンショット 2025-07-11 16.07.54.png

これをちゃんと動くように変更していきます。

許可されているコールバックURLを変更

AWSのマネコンに戻ります。

「アプリケーション」→「アプリケーションクライアント」→「My SPA app」→「ログインページ」にて「編集」します。

スクリーンショット 2025-07-11 16.10.05.png

許可されているコールバックURLを次のように変更して下さい。

http://localhost:5173/

また、許可されているサインアウトURLにも同じURLを入力します。

スクリーンショット 2025-07-11 16.12.54.png

「変更を保存」します。

スクリーンショット 2025-07-11 16.15.58.png

✅ これでログイン後に、ローカルホストで立ち上げてるページにリダイレクトされるようになりました。再度ログインを試していきます。

スクリーンショット 2025-07-11 16.17.45.png

今度はCognitoのログイン画面に飛びました!

スクリーンショット 2025-07-11 16.17.52.png

「Continue with Okta」でログインすると下記のような表示がされると思います。

スクリーンショット 2025-07-11 16.18.05.png

「Quick Setup ガイド」の実装は以上になります。

いくつかこの状態だと気になる部分があります(例えばリロードするとエラー画面になるとか)。この辺りを修正していく実装は、また別の記事で紹介できたらと考えています。

認証コード→アクセストークン交換

やはり、このページのURLにもアクセストークではなくcodeが付与されています。このcodeをどうアクセストークンに交換してるかと言う部分を確認しておきます。

と言っても実装はライブラリ任せです。

ここでは、ちゃんと交換されてるよね?という事だけ確認します。

ブラウザの開発者ツールの「Network」タブを開きます。

文字小さいですが「token」と言う項目があるのを確認できますでしょうか?

スクリーンショット 2025-07-11 16.21.00.png

クリックして「Payload」を開くと「https://ap-northeast-1_Lmyjqhqf0.auth.ap-northeast-1.amazoncognito.com/oauth2/token(※)」に対してcodeを送ってることを確認できます。

※ドメインは適宜自分のものと読み替えて下さい。

スクリーンショット 2025-07-11 16.33.59.png

更にその「Response」を確認するとトークンが返って来てる事を確認できます。

スクリーンショット 2025-07-11 16.34.07.png

この記事でPKCE認証についてこれ以上は触れませんが、一旦、トークンを取得するには認可コードと引き換えないといけないんだな、と覚えておいて貰えたら良いかと思います。

✅ この記事での実装は以上になります!!お疲れ様でしたー!!

終わりに

冒頭でも触れましたが、この記事は、2年前に執筆した内容をもとに、現在(2025年7月)のAWSの画面や仕様に合わせてリライトしたものです。当時からAWSの画面がだいぶ変わってしまっていて「これはもう使えないな…」と思い、最新の内容で書き直しました。

ちなみに、この記事と同じ内容をハンズオン形式で解説した動画をYouTubeにもアップしています。実際の操作画面を見ながら進めたい方は、ぜひチェックしてみてください!

ここまで読んでいただき、ありがとうございましたー!

13
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?