CognitoとAuto0をSAML連携してみた。



## はじめに

前回記事にしたGoogleアカウントを使ったID連携はOAuth２.0 Authorization Code Flowを使用したOIDC認証フローですが、今回は別形式のSAMLを使ったID連携を試してみます。

https://qiita.com/s_moriyama/items/c4304100a091986eb3fe

### SAML（さむる）とは？

丸投げですが、SAMLの細かな説明は以下ページを見ていただければ、と思います。

https://www.intra-mart.jp/im-press/useful/security_assertion_markup_language

まずは、`OAuth 2.0`、`OIDC`、`SAML`の役割の違いをざっくりと理解しておくと良いのではと思います。

今回は`OAuth 2.0`、`OIDC`、`SAML`の役割をClaudeに要約させてたいので、参考までに載せておきます！

##### OAuth 2.0
| 項目 | 内容 |
|------|------|
| 用途 | APIアクセスの認可 |
| 仕組み | アクセストークンでリソースにアクセス |
| 特徴 | 認証はしない、認可専用 |

##### OIDC（OpenID Connect）

| 項目 | 内容 |
|------|------|
| 用途 | 認証 + 認可 |
| 仕組み | OAuth 2.0 + IDトークン（ユーザー情報） |
| 特徴 | SSOに最適 |

##### SAML

| 項目 | 内容 |
|------|------|
| 用途 | エンタープライズSSO |
| 仕組み | XMLベースのアサーション（認証証明） |
| 特徴 | 古いシステムに強い |

## やってみた！

では、やってみます。

最初はOktaでやってみようかと思ったのですが、gmailアカウントだとアカウント登録できないようでしたので、今回はAuth0を使ってみました。

https://auth0.com/jp

### Auth0アプリケーションの作成

最初にアプリケーションを作っていきます。
他のサービスでいうクライアントに相当するところなのかな。

![スクリーンショット 2025-05-06 5.45.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894042/064eced5-1d59-459f-ad65-0207e5977723.png)

名前は適当に。今回はSPAを選びます。

![スクリーンショット 2025-05-05 5.57.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894042/9c4b5310-1450-4d01-a297-361d9ebe9636.png)

### Application URIs設定

次に`Settings`の`Application URIs`を以下のように設定します。

`Allowed Callback URLs`のところは、SAML専用のエンドポイントがあるので注意ですね！

|項目|設定値|
|--|--|
|Application Login URI|https://[ドメイン名].auth.ap-northeast-1.amazoncognito.com|
|Allowed Callback URLs|https://[ドメイン名].auth.ap-northeast-1.amazoncognito.com/**saml2/idpresponse**|
|Allowed Logout URLs|http://localhost:3000|
|Allowed Web Orgins|http://localhost:3000|

![スクリーンショット 2025-05-05 6.10.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894042/141b523e-bb5a-4eb8-bb8d-a94a73dc98ac.png)

次に、`Addon`から`SAML2`を選択し、`Setting`タブ内から、ログアウト時にURIの指定をします。

```json
{
  "logout": {
    "callback": "http://localhost:3000",
    "slo_enabled": "false"
  }
}
```

![スクリーンショット 2025-05-05 6.12.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894042/93151387-c14a-4e03-b4e3-1fafe81cdf74.png)

この設定がなぜ必要なのかが分からず、設定の仕方が合ってるか悩ましいのですが、この設定がないとログアウト時の画面遷移が正しく動作しませんでした。

### SAML IdPメタデータファイル取得

最後に、Cognito設定時に利用するメタデータファイルをダウンロードしておきます。
このファイルにはSAML認証時のエンドポイントや、署名検証を行うX509証明書などが記載されています。

![スクリーンショット 2025-05-05 6.13.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894042/a719482b-00af-4a97-8eae-15167f24dee8.png)

これでAuth0側の設定は完了です！

### Cognitoの設定（カスタムプロバイダーの追加）

ユーザプールの以下からAuth0の設定を行います。

![スクリーンショット 2025-05-05 6.16.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894042/546be524-69ac-4c20-aa96-8c4d5ed0970d.png)

![スクリーンショット 2025-05-05 6.17.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894042/c61eabb3-1255-4f66-999c-a9e512fbec18.png)

名前をつけてあげて、SAML IdPメタデータファイルをアップロードするだけです。

![スクリーンショット 2025-05-05 6.20.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894042/fde08ff3-3b8e-45b1-8b4f-70472cc858d3.png)

最後に属性のマッピングをします。

![スクリーンショット 2025-05-05 6.20.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894042/3270d216-3fa9-431e-abe4-6624efbb4932.png)

SAML属性ですが、Auth0だと以下のところの`Debug`からアサーションが確認できるので、ここを参考に設定します。

今回は`name`を`http://schemas.auth0.com/username`でマッピングします。

![スクリーンショット 2025-05-06 6.42.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894042/52e46e6e-8078-4dcf-a6f7-a7f2c8405f90.png)

### Cognitoの設定（クライアント設定）

最後に、クライアントのIDプロバイダーに先ほど設定したAuth0の設定を追加すれば完了です！

![スクリーンショット 2025-05-05 6.22.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894042/cf53159f-ee6f-45c9-b551-4e186c864f9a.png)

これで、マネージドログイン画面にAuth0も追加されました！
![スクリーンショット 2025-05-06 6.51.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894042/e9711276-23d8-4736-8ade-4f246d61c6fe.png)

実際に選択してみると、Auth0のログイン画面が表示されます。

![スクリーンショット 2025-05-05 6.23.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894042/b017b8ae-efe5-4046-bb71-723eadf44fa6.png)

## 動作確認

少し動作確認してみます。

### 処理シーケンス

Chromeで取得できるネットワークログからシーケンス図を作ってみました。

SAML 2.0とOAuth 2.0/OIDCのハイブリッドフローになっていることがわかると思います。

```mermaid
sequenceDiagram
    participant User as ユーザー
    participant App as アプリケーション (localhost:3000)
    participant Cognito as Amazon Cognito
    participant Auth0 as Auth0 (IdP)

    User->>App: アプリケーションへアクセス
    
    %% OAuth/SAML認証フロー
    App->>Cognito: OIDC認可リクエスト
    Note over App,Cognito: identity_provider=Auth0, response_type=code など
    
    Cognito->>Auth0: SAMLRequestを含むリダイレクト
    Auth0->>User: ログインページを表示
    User->>Auth0: 認証情報を送信 (ユーザー名/パスワード)
    Note over User,Auth0: ユーザー名: xxxxxxx@gmail.com
    
    Auth0->>Auth0: ユーザー認証
    Auth0->>Cognito: SAMLレスポンスを/saml2/idpresponseにPOST
    Note over Auth0,Cognito: ユーザー属性、認証アサーションを含む
    
    Cognito->>App: 認可コードを含むリダイレクト
    Note over Cognito,App: code=c80de796-116c-4f7b-a908-1217801ac01c
    
    App->>Cognito: トークンリクエスト (POST /oauth2/token)
    Note over App,Cognito: 認可コードをトークンと交換
    
    Cognito->>App: トークン返却 (ID, アクセス, リフレッシュ)    

```

### IDトークン

ID連携して、取得したIDトークンを覗いてみます。

IdPがAuth0であることや、ユーザ名`moriyama_saml`が取得できていることがわかります。

```json
{
  "at_hash": "fTyFKK1CI_nygSE8h3kN9A",
  "sub": "17a4ca28-9041-7078-7042-53c919xxxxxx",
  "cognito:groups": [
    "ap-northeast-1_xxxxxxxxx_Auth0SAML"
  ],
  "iss": "https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_xxxxxxxxx",
  "cognito:username": "auth0saml_auth0|6817db56a810172c42865000",
  "nonce": "-D0I1sJlzLIMwx4qOnsO3US7yr8Nw1AJj8GC-1VAcam2o9PaJ6IX8yOf3iiEgcxtzKHOyQTNZ6JAliFxqsXrYkMAXVaRyTVQh7s1_YgInOtJEjl5bjV4plCEkO8Q2Qw9KQj54VWLPKc3hzCpnMkoqMyk3G_-7LQ7PVemv-16dm0",
  "origin_jti": "b069ac48-330e-451a-a6fa-58b988fdbc88",
  "aud": "ar4sjg7u1g1t16cah2rjfkxxx",
  "identities": [
    {
      "dateCreated": "1746393943191",
      "userId": "auth0|6817db56a810172c42865000",
      "providerName": "Auth0SAML",
      "providerType": "SAML",
      "issuer": "urn:dev-ryrknqlogokxxxxx.us.auth0.com",
      "primary": "true"
    }
  ],
  "token_use": "id",
  "auth_time": 1746393943,
  "name": "moriyama_saml",
  "exp": 1746397543,
  "iat": 1746393944,
  "jti": "f5cc7429-b061-476f-a460-9e3b59774632"
}
```

![スクリーンショット 2025-05-07 3.57.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894042/13612ce2-f541-431b-8885-a9b5c9f75100.png)

## 最後に

簡単に、ではありますが、2回に分けてID連携を確認できました。

身近な機能ですが、中身の挙動を垣間見ることができてよかったです！