【AWS ALB】OneGateのOIDC認証連携

水色の背景に六角形が2つあるイラスト 水色の背景に六角形が2つあるイラスト
アイキャッチ
目次

はじめに

これまで、Soliton OneGate(以下、OneGate)を使って AWS Application Load Balancer(以下、ALB)をセキュアにする方法として、「SSLオフロード」や「mTLS認証」を紹介しました。


Soliton OneGate証明書で実現!AWS ALBのSSLオフロード設定ガイド

OneGate発行のサーバー証明書を使い、AWSのALBでSSLオフロードを実現する手順を解説。Webサーバーの負荷軽減とセキュリティ向上を両立させる具体的な構築方法を、VPC作成から丁寧に紹介します。

netattest.com

og_img

【AWS ALB】OneGate連携 mTLS認証で安全なアクセス制御を実現する設定方法

AWS ALBでOneGate発行のクライアント証明書を使ったmTLS認証設定を徹底解説。S3バケット作成、トラストストア、リスナー設定から証明書失効時のCRL更新まで、Webサーバーへの強固なアクセス制御を実現する手順を詳細に紹介します。

netattest.com

og_img

【AWS】ALBのmTLS認証CRL自動更新をCLIとSystemdで効率化!OneGate連携設定

AWS ALBとOneGate連携mTLS認証におけるCRL更新作業を自動化する方法を徹底解説。AWS CLIとSystemd Timerを使ったS3へのアップロード、トラストストア反映、IAM/S3ポリシー設定まで、証明書管理の手間を大幅削減します。

netattest.com

og_img

mTLS認証は強力ですが、近年では「端末」だけでなく「ユーザー本人」の確認や、アクセスの状況に応じた柔軟な制御が求められています。
そこで今回は、2025年秋のアップデートでOneGateが対応した 「OIDC認証」 を利用し、ALBの認証をより強固なものにする構成を紹介いたします。

なぜ、mTLSだけではなくOneGateでの認証なのか?

「OneGateから発行したクライアント証明書で、許可された端末以外はブロックできているから十分では?」

そう思われる方も多いかもしれません。この構成ならOneGateのPKIプランで比較的安価に構築できます。

端末認証は強力ですが、OneGate Basicプラン以上で使えるOIDC認証を組み合わせることで、認証の「質」 が変わるメリットがあります。

OneGateで認証することによるメリット

ALBの認証をOneGateに向けることによるメリットは次の通りです。

  1. 証明書失効の即時反映(運用工数の削減)
    ALB単体でmTLSを行う場合、紛失した端末の証明書を無効化するには、CRL(証明書失効リスト)の定期更新など手間のかかるAWS側の運用が必要です。 一方、OneGate連携であれば、管理画面で証明書を失効させるだけで即座にログインができなくなります。 タイムラグなく緊急対応が完了するのは、運用者にとって大きなメリットです。
  2. 「証明書(端末)」+「認証(人)」の非常に強固な組み合わせ
    単にID/パスワードでログインさせるだけでなく、「有効な証明書が入った端末でのみ、ログイン試行を許可する」 という制御が可能です。 これにより、万が一ID・パスワードが漏洩しても、会社が許可した端末以外からはアクセス自体ができないため、不正アクセスを確実に防ぐことができます。
  3. パスワードレスやコンテキストに応じた柔軟性
    OneGateの認証機能を使えば、本人確認の要素として、ID/パスワード以外にも「スマートフォンアプリでの承認(Soliton Authenticator)」、「顔認証」(オプション)、「FIDO2デバイス」、「ICカード」などを選択・組み合わせ可能です。 また「社内から証明書なしで」、「社外からは証明書+顔認証で」、「普段のアクティビティと異なる場合には2段階の認証を求める」といった、場所や状況(コンテキスト)に応じた柔軟なルールも適用できます。
  4. 認証のオフロードによるアプリケーション連携
    ALBが認証済みのユーザー情報をHTTPリクエストヘッダーとしてアプリに渡すことができます。
    既存アプリをHTTPリクエストヘッダーで認証する改修工数はそれなりにかかりますが、「アプリ側に複雑な認証ロジックを実装せず、OneGateに任せられる」 点は、長期的な開発・運用コストの削減につながります。
    また、既存のレガシーアプリをクラウド移行(モダナイゼーション) していく過程においても、HTTPリクエストヘッダー認証による認証ロジックの分離は有効な手段となります。

ALBとOneGateを認証連携させる設定

ALBとOneGateを認証連携させる環境を構築します。 AWS上にWebサーバーを構築してALB経由でアクセスする手段は以前ご紹介した通りですので割愛します。 ALBの構築手順についてはOneGateから発行した証明書を使ってAWS ALBをセキュアにする-その1「SSLオフロード」をご参照いただければと思います。

ALBで直接OIDC認証連携するか、Cognitoを経由するか

ALBでOIDC認証する場合、ALBにOIDCの認証連携の設定を入れる方法とOIDC認証が設定されているCognitoをブローカーとして使う方法があります。

それぞれのメリット・デメリットを簡単にまとめてみました。

特徴ALBに直接OIDC設定するCognitoをブローカーにする
構成の複雑さシンプル(ALBとOneGateのみ)要素が増える(ALBとOneGateとCognito)
AWSのコストALBの料金のみALBとCognitoの料金がかかる
ユーザー情報の扱いALBはユーザー情報を永続的には保持せず、セッション情報のみを管理しますCognitoユーザープールに情報が保存される
AWSの他のサービスとの連携Webサーバーにヘッダー情報を渡すのみAPI GatewayやIAMなどと連携が可能
複数のIdP(認証サーバー)利用不可可能
例)社員はSoliton OneGate、協力会社は他のIdPなど、複数のIdPを使用することが可能

今回の構成ではALBが提供するOIDC認証機能の動作確認を目的としますので、Cognitoは使用せずにシンプルにALBに直接OIDC設定を行うようにします。

構成図

本記事の検証構成は次の通りです。  今回はALBの認証機能を検証する目的のため、下記のように簡素化した構成にしてあります。

  • ALBではTLS終端(SSLオフロード)のみを行う
    • クライアントPCとALB間はHTTPS
    • ALBとWebサーバー(Amazon Linux 2023)間はHTTP
  • ap-northeast-1aとap-northeast-1cにサブネットがあり、それぞれのサブネットにAmazon Linux 2023を設置して、それらをALBのターゲットグループにしてあります
    • Amazon Linux 2023には下記の手順でNginxをインストールしてWebサーバー化しています
    • Webページのデザインは生成AIを活用して作成しました
  • セキュリティグループ設定は次の通り
    • ALBセキュリティグループ:インバウンドで社内からのHTTPSのみ許可/アウトバウンドは全許可
    • Webサーバーのセキュリティグループ:インバウンドルールでALBのセキュリティグループからHTTPのみ許可/アウトバウンドは全許可
  • その他、AWSは必要最低限の設定にとどめています。

<参考:Amazon Linux 2023にNginxをインストール>

# パッケージの更新とNginxインストール
sudo dnf update -y
sudo dnf install nginx -y

# 起動と自動起動設定
sudo systemctl enable --now nginx

# 状態確認(Active: active (running) ならOK)
systemctl status nginx

<参考:ap-northeast-1aのAL2023 Webページサンプル>

sudo sh -c 'cat <<EOF > /usr/share/nginx/html/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ALB Test - Server 1</title>
<style>
  body {
    background-color: #E3F2FD; /* 薄い青 */
    color: #0D47A1;
    font-family: sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
  }
  .card {
    background: white;
    padding: 2rem;
    border-radius: 10px;
    box-shadow: 0 4px 6px rgba(0,0,0,0.1);
    text-align: center;
  }
</style>
</head>
<body>
  <div class="card">
    <h1>Server 1 🔵</h1>
    <p>This response is from the <strong>FIRST</strong> instance.</p>
    <p>Target Group Health Check: OK</p>
  </div>
</body>
</html>
EOF'

<参考:ap-northeast-1cのAL2023 Webページサンプル>

 sudo sh -c 'cat <<EOF > /usr/share/nginx/html/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ALB Test - Server 2</title>
<style>
  body {
    background-color: #E8F5E9; /* 薄い緑 */
    color: #1B5E20;
    font-family: sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
  }
  .card {
    background: white;
    padding: 2rem;
    border-radius: 10px;
    box-shadow: 0 4px 6px rgba(0,0,0,0.1);
    text-align: center;
  }
</style>
</head>
<body>
  <div class="card">
    <h1>Server 2 🟢</h1>
    <p>This response is from the <strong>SECOND</strong> instance.</p>
    <p>Target Group Health Check: OK</p>
  </div>
</body>
</html>
EOF'

OneGateでALBの認証をSSOする設定

OneGateでサービス連携設定を行います。

  1. OneGateの管理ページの[クラウド設定]>[サービス連携設定]を開き「登録」をクリックします。
  2. 下記を設定して「保存」をクリックします。
    • クラウドサービス設定
      項目
      クラウドサービス名SSO設定名です。任意の値を入れます。
      例)ALB-OIDC認証
      クラウドサービスの概要SSO対象のクラウドサービスの説明を入力します。空欄でも問題ございません。
      ALB配下のWebアプリアクセス用
      備考クラウドサービスについての説明の補足等を入力します。空欄でも問題ございません。
    • SAML設定
      項目
      SAML設定「SAMLを使用する」のチェックを外します
    • OpenID Connect設定
      項目
      OpenID Connect設定「 OpenID Connectを使用する」のチェックを入れます
      リダイレクトURIhttps://ALBのDNS名/oauth2/idpresponseを入力します。
      注意:ALBの設定名に大文字が含まれている場合は、リダイレクトURLではすべて小文字にします。
    • OpenID Connect詳細設定
      項目
      署名アルゴリズムRS256

  3. 設定したSSO設定をクリックします。
  4. 下記のように設定し、クライアントID及びクライアントシークレットの値を控えて保存をクリックします。
    • 情報資産設定
      項目
      SSOプルダウンメニューから「SSO先として利用する」を選択します。
      セキュリティレベルチェックをオフにします。
      IdP証明書メニューアイコン(≡)をクリックして「Current Certificate」を選択します。
      認証タイプ「OpenID Connect」が選択された状態にします。
    • OpenID Connect設定
      項目
      ユーザー名任意のSSO User Xを選んでください。
      クライアントID表示されている値をコピーして、保存しておきます。
      この値はALBの設定変更時に使用します。
      クライアントシークレット「発行」ボタンをクリックして、生成された値をコピーして保存しておきます。
      この値はALBの設定変更時に使用します。
  5. [クラウド設定]>[共通設定]に表示されている「OpenID Providerメタデータ」の値を控えておきます。
    この値はALBの設定変更時に使用します。

OneGateユーザーにアプリケーション利用権限を与える

OneGateのユーザーに作成したサービス連携設定の利用許可(アプリケーションロール)を与えます。

今回は、あらかじめ作成してあるテストユーザー「alb-user01」に設定する手順を紹介します。

手動での新規登録、ADやEntra ID連携、CSVによる一括登録・変更についてはSoliton OneGate管理者ガイドをご参照ください。

  1. OneGate管理ページの[利用者管理]>[利用者一覧]を開き、「alb-user01」を開きます。
  2. 「アプリケーションロール」欄の「+」をクリックします。
  3. 作成したサービス連携設定名にチェックを入れて「OK」をクリックします。
  4. 「SSO User X」(今回のサービス連携設定の場合には「SSO User 1」)にALBに伝えたいユーザー名を入力して「保存」をクリックします。
    この値はALBを通じてターゲットグループのWebサーバーにHTTPヘッダーとして転送されます。(厳密には転送されるように後の工程でALBの設定を変更します。)

ALBの設定変更

ALBからOneGateにOIDC認証連携するように設定変更します。

  1. EC2ダッシュボードの[ロードバランシング]-[ロードバランサー]を開き、設定変更するALBを選択して、「リスナーとルール」タブの「HTTPS:443」にチェックを入れ、「リスナーの管理」プルダウンメニューから「リスナーの編集」をクリックします。
  2. [リスナーの詳細]-[デフォルトアクション]-[事前ルーティングアクション]にて「ユーザーを認証」にチェックを入れて、下記のように設定して、「変更内容の保存」をクリックします。
    項目
    アイデンティティープロバイダーOIDC(OpenID Connect)
    発行者OneGate管理ページの「OpenID Providerメタデータ」に表示されていた「発行者」の値を入力します。
    認証エンドポイントOneGate管理ページの「OpenID Providerメタデータ」に表示されていた「認可エンドポイントのURL」の値を入力します。
    トークンエンドポイントOneGate管理ページの「OpenID Providerメタデータ」に表示されていた「トークンエンドポイントのURL」の値を入力します。
    ユーザー情報エンドポイントOneGate管理ページの「OpenID Providerメタデータ」に表示されていた「ユーザー情報エンドポイントのURL」の値を入力します。
    クライアントIDクラウドサービス連携設定で控えていたクライアントIDを入力します。
    クライアントのシークレットクラウドサービス連携設定で生成し控えていたクライアントシークレットを入力します。
    • 高度な認証設定
      項目
      スコープ「openid profile」にします。

ALBにアクセスしてみる

設定が完了したら、実際にALBにアクセスしてみます。

  1. ブラウザでALBにアクセスします。
  2. OneGateにリダイレクトされますので、ALBのアプリケーションロールが割り当てられた利用者で認証します。(顔認証にしてみました)

  3. 認証に成功するとWebサーバーにアクセスできます。
  4. ブラウザをリロードするとロードバランサーでもう片方のWebサーバーが表示されます。

ALBアクセスからOneGate認証の流れ

上記のようにALBにアクセスして、OneGateにリダイレクトされて認証して、Webアプリが表示されるまでの流れについて、ブラウザの開発ツールを使って中身の流れを確認してみます。

  1. ブラウザがALBにアクセスすると、ALBは、IdP(認証サーバー:OneGate)へのリダイレクトURLをLocationヘッダーにセットし、同時にAWSALBAuthNonceクッキーを発行して、ブラウザにレスポンス(302 Found)を返します。
  2. OneGateにリダイレクトして認証に成功すると、クエリーに認可コード(Authorization Code)を含んだALBへのコールバックURLへリダイレクトさせます。 
  3. ALBに対して1で発行されたAWSALBAuthNonceクッキーとともに、コールバックURLへアクセスします。
  4. ALBはAWSALBAuthNonceクッキーを照合して、認可コードを使用してOneGateと通信してトークンを取得します。
  5. ALBはブラウザに対してトークンを埋め込んだAWSELBAuthSessionCookie-xクッキーを発行します。
  6. ブラウザは以後ALBへのアクセスはこのAWSELBAuthSessionCookie-xクッキーを用いてアクセスします。

この流れをフロー図にすると以下になります。  なおクッキーの詳細は次の通りです。

  • AWSALBAuthNonce ALBでの認証管理用のクッキーです。OIDCで認証の場合、ALBを離れて(リダイレクト)、その後戻って来る(コールバック)動作になるため、どのアクセスがリダイレクトされ、コールバックしたものかを判断するためのものになります。
    有効期限は15分間となります。
  • AWSELBAuthSessionCookie-x ALBとブラウザのセッション管理用のクッキーです。OIDCで認証済みのブラウザかどうかを判断するのに使用されます。
    xの部分は数字が入り、通常は0ですが、クッキーのサイズが大きい場合にはAWSELBAuthSessionCookie-0AWSELBAuthSessionCookie-1のように分割します。
    有効期限はALBのリスナー設定のセッションタイムアウトで設定します。(デフォルト7日)
    デフォルトでは7日間は認証無しでアクセスできてしまいますので、適切なセッションタイムアウトを設けるか、Webサーバー側でログアウトボタンをクリックした際に、Set-Cookie: AWSELBAuthSessionCookie-0=; Max-Age=0;のようなヘッダーを作って、ブラウザに保持されているAWSELBAuthSessionCookie-xクッキーを期限切れで上書きするなどの処理を検討してください。

ALBからターゲットグループにどのような情報が伝えられているか

序盤でALBの認証をOneGateに向けることのメリットの一つとして認証のオフロードによるアプリケーション連携としてHTTPリクエストヘッダーを説明しましたが、ALBからターゲットグループのWebサーバーにどのようなHTTPリクエストヘッダーが渡されるかを確認します。 Application Load Balancer を使用してユーザーを認証する-ユーザークレームのエンコードと署名の検証によると、ALBが下記3つを付与してターゲットグループに転送すると書いてあります。

  • x-amzn-oidc-accesstoken
  • x-amzn-oidc-identity
  • x-amzn-oidc-data

今回はALBからターゲットグループへはHTTP(TCP/80)と平文での通信であるので、Webサーバー上で下記のようにパケットキャプチャを取得してみて、OneGateで認証した端末がWebアクセスするとALBからどのようなヘッダーが飛んでくるか確認してみます。

 sudo tcpdump -i any -A port 80 | grep -i "x-amzn-oidc"
 [ec2-user@netattest-web ~]$ sudo tcpdump -i any -A port 80 | grep -i "x-amzn-oidc"
tcpdump: data link type LINUX_SLL2
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
X-Amzn-Oidc-Data: eyJ0eXAiOij<中略>AyNTc1NDR9.eyJzdWIiOi<中略>MuanAifQ==.ow8C4i0pPx<中略>EvpWhsqA==
X-Amzn-Oidc-Identity: 54366
X-Amzn-Oidc-Accesstoken: znrS4X<中略>5J0UE8

※セキュリティの都合で一部省略しました。 

さて、ユーザーを識別できる情報としてはx-amzn-oidc-identityがありますが、あまり見覚えのない数値データとなっています。
そこで、まずはx-amzn-oidc-dataの中身を確認して、ユーザーを識別できる情報があるか確認してみます。

x-amzn-oidc-data

このヘッダーはOneGateから取得したユーザークレーム、つまりOIDC認証したユーザーの詳細になります。

 eyJ0eXAiOij<中略>AyNTc1NDR9.eyJzdWIiOi<中略>MuanAifQ==.ow8C4i0pPx<中略>EvpWhsqA==

この値はJWT(JSON Web Token)であり中身はbase64URLエンコードされたJSONデータであるため、Linux環境によってはbase64 -dでデコードできます。
ただしJWTの値を見ると.(ドット)が含まれています。これはJWTがドット区切りでヘッダー.ペイロード(クレームの中身).署名で構成されていますので、クレームの中身だけをみるには

 echo "<x-amzn-oidc-dataの値>" | cut -d "." -f 2 | base64 -d

のように1つ目のドットと2つ目のドットの間だけをbase64でデコードする必要があります。

 [ec2-user@netattest-web ~]$ echo "eyJ0eXAiOij<中略>AyNTc1NDR9.eyJzdWIiOi<中略>MuanAifQ==.ow8C4i0pPx<中略>EvpWhsqA==" | cut -d "." -f 2 | base64 -d
{"sub":"54366","given_name":"User01","family_name":"ALB","zoneinfo":null,"locale":null,"exp":1770257544,"iss":"https://<Soliton OneGate>"}
[ec2-user@netattest-web ~]$

※姓、名に全角カナを含ませた場合、JWTとbase64の仕様の差(パディング数、使う記号)でうまくデコード出来ない場合があります。その場合にはpythonを使って

 echo "<x-amzn-oidc-dataの値>" | cut -d "." -f 2 | python3 -c "import sys, base64; print(base64.urlsafe_b64decode(sys.stdin.read() + '===').decode('utf-8'))"

を試してみてください。 

さて、デコードされた値は次のとおりでした。(JSON部分が見やすいように改行を入れました)

 {
    "sub": "54366",
    "given_name": "User01",
    "family_name": "ALB",
    "zoneinfo": null,
    "locale": null,
    "exp": 1770257544,
    "iss": "https://<Soliton OneGate>"
}
項目説明
sub54366認証プロバイダ(今回はSoliton OneGate)上でユーザーを一意に識別するためのIDになります。x-amzn-oidc-identityの値もこれになります。
given_nameUser01OneGateで設定した名(First Name)の値になります。
family_nameALBOneGateで設定した姓(Last Name)の値になります。
isshttps://<Soliton OneGate>IDトークンの発行者
exp1770257544IDトークンの有効期限(UnixTime)

subの値はOneGateの内部で管理している値のためOneGateの管理画面等では見ることが出来ない値ですが、ログ転送を有効にしてTLS通信のSyslogサーバーにログを転送すると、OIDCによる認証を行ったときのSSOアクセスログ("log_type":"sso_access")にemployee_idとして表記されています。

 2026-02-05T02: 07: 37+09: 00 OneGate idp {
    "timestamp": "2026-02-05T02:07:37.335+00:00",
    "tenantcode": "テナント名",
    "log_level": "INFO",
    "log_type": "sso_access",
    "message": "Access Permission",
    "params": {
        "employee_id": 54366,
        "cloud_service_id": 15071,
        "ip_address_text": "xxx.xxx.xxx.xxx",
        "service_ip_address_text": "xxx.xxx.xxx.xxx",
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
        "success_flag": true,
        "saml_log": null,
        "office365_auth_type": 2
    }
}

さて、Webアプリ側でHTTPリクエストヘッダーを用いた認証を実装した場合にヘッダーの情報だけでうまくユーザーを一意に識別することができるのでしょうか?

  • subをユーザー識別に使用すると?
    OneGateで管理している一意の値ですが、この値はOneGateで自動に割り振った値であり、かつOneGateの管理画面から取得するのが難しいため、Webアプリ側で「54366はUser01さん」と紐づけるのは難しそうです。
  • given_nameやfamily_nameをユーザー識別に使用すると?
    この値はALBのリスナー設定のスコープでprofileを追加したことによってIDトークンに含まれる値となります。(profileがない場合にはsub、iss、expのみになります) 日本での運用としては全角カナ文字を使用することが多いので、ID情報として使用するにはシステムによっては制約がある可能性があります。

今のままではHTTPリクエストヘッダーの認証に使用するのは難しそうですので、OneGateの管理画面上でも見れる別の値(ログイン名やSSO User X)をIDトークンに含ませたいと思います。

IDトークンのクレームに含ませる方法はprofileと同じくスコープで指定します。ALBで指定することができるスコープはemail、name、openid、postal_code、profile、public_profileとなりますので、ここではnameを追加します。

  1. EC2ダッシュボードの[ロードバランシング]-[ロードバランサー]を開き、設定変更するALBを選択して、「リスナーとルール 」タブの「HTTPS:443」にチェックを入れ、「リスナーの管理」プルダウンメニューから「リスナーの編集」をクリックします。
  2. [リスナーの詳細]-[デフォルトアクション]-[事前ルーティングアクション]の「高度な認証設定」を下記のよう設定して「変更内容を保存」をクリックします。
    項目
    スコープ「openid profile name」にします。

この設定でALB側はIdPに対してnameの値をIDトークンに含めるように要求します。

これで再度ALBで認証してみて、パケットキャプチャしてみます。

 [ec2-user@netattest-web ~]$ sudo tcpdump -i any -A port 80 | grep -i "x-amzn-oidc"
tcpdump: data link type LINUX_SLL2
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
X-Amzn-Oidc-Data: eyJ0eXAiOi<中略>AyNzAxNTh9.eyJzdWIiOi<中略>lzLmpwIn0=.y84ZHvj3z1<中略>4Y92mfgw==
X-Amzn-Oidc-Identity: 54366
X-Amzn-Oidc-Accesstoken: 1B634J3Obj<中略>vNQuRz7FjQ
^C7 packets captured
9 packets received by filter
0 packets dropped by kernel


[ec2-user@netattest-web ~]$ echo "eyJ0eXAiOi<中略>AyNzAxNTh9.eyJzdWIiOi<中略>lzLmpwIn0=.y84ZHvj3z1<中略>4Y92mfgw==" | cut -d "." -f 2 | base64 -d
{"sub":"54366","given_name":"User01","family_name":"ALB","preferred_username":"albUser01","zoneinfo":null,"locale":null,"exp":1770270158,"iss":"https://<Soliton OneGate>"}
[ec2-user@netattest-web ~]$

こちらもJSON部分が見やすいように改行を入れて表示しました。

  {
    "sub": "54366",
    "given_name": "User01",
    "family_name": "ALB",
    "preferred_username": "albUser01",
    "zoneinfo": null,
    "locale": null,
    "exp": 1770270158,
    "iss": "https://<Soliton OneGate>"
}

スコープにnameを追加したところ、SSO User Xで設定した値をpreferred_usernameとしてIDトークンに含めることができましたので、preferred_usernameを使ってWebアプリ側でHTTPリクエストヘッダーを用いて認証するのもよいかもしれません。

また最近のクラウドサービスではemail属性を使うことが多いと思います。OneGate利用者にemailを設定している場合には、ALBリスナーのスコープ設定にemailを入れると、emailの値もクレームに含めることができます。 

リスナーのスコープ設定


OneGate利用者のメールアドレス設定

 [ec2-user@netattest-web ~]$ sudo tcpdump -i any -A port 80 | grep -i "x-amzn-oidc"
tcpdump: data link type LINUX_SLL2
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
X-Amzn-Oidc-Data: eyJ0eXAiOi<中略>AzMzk1MDJ9.eyJzdWIiOi<中略>N5cy5qcCJ9.MjyKPJG256<中略>7ndxA2CQ==
X-Amzn-Oidc-Identity: 54366
X-Amzn-Oidc-Accesstoken: ZoFQYgWMlv<中略>pMk6FfFY25
^C71 packets captured
73 packets received by filter
0 packets dropped by kernel


[ec2-user@netattest-web ~]$ echo "eyJ0eXAiOi<中略>AzMzk1MDJ9.eyJzdWIiOi<中略>N5cy5qcCJ9.MjyKPJG256<中略>7ndxA2CQ==" | cut -d "." -f 2 | base64 -d
{"sub":"54366","given_name":"User01","family_name":"ALB","preferred_username":"sso-albUser01","zoneinfo":null,"locale":null,"email":"alb-user01@sog.example","email_verified":true,"exp":1770339502,"iss":"https://<Soliton OneGate>"}

こちらもJSON部分が見やすように改行を入れてみました。

 {
    "sub": "54366",
    "given_name": "User01",
    "family_name": "ALB",
    "preferred_username": "sso-albUser01",
    "zoneinfo": null,
    "locale": null,
    "email": "alb-user01@sog.example",
    "email_verified": true,
    "exp": 1770339502,
    "iss": "https://<Soliton OneGate>"
}

この他、OneGateでは「カスタムクレーム」の機能を使って、OneGate利用者の任意の属性をRP(今回の構成ではALB)が対応している任意のクレーム属性として使用することができます。

利用できる属性や、カスタムクレームの設定方法についてはOneGate管理ガイドをご参照ください。

HTTPリクエストヘッダー認証におけるセキュリティ上の注意点

さて、ここまでHTTPリクエストヘッダーにユーザーを識別する属性値を含められることを紹介しましたが、HTTPリクエストヘッダーを使った認証ではセキュリティ面で意識していただきたい点があります。

HTTPリクエストヘッダーを使った認証ではWebアプリケーションがどこからアクセスされているか? が大変重要になります。もし悪意ある人がALB以外の経路でWebアプリケーションにアクセスしてしまうと、ヘッダーを偽装して別人になりすましてWebアプリにアクセスすることが可能になってしまいます。

それを防ぐためにAWSならびにWebアプリケーション側で下記の点をご考慮いただければと思います。

  • WebアプリへのHTTP通信を、ALB(のセキュリティグループ)からのみ許可するようセキュリティグループを設定する
    WebサーバーのOS上でFirewallを設定していただいてもいいのですが、サーバーが複数ある場合の設定管理の煩雑さ、特にコンテナ環境などではOS側での制御が複雑になりがちなため、AWSのセキュリティグループを用いて、インフラ層で確実にアクセス元を絞る設計を強く推奨します。
  • Webアプリでx-amzn-oidc-dataに含まれるALBの署名について検証する
    x-amzn-oidc-dataに含まれている署名を検証して、アクセス元がALBであること確認することもできます。HTTPアクセスがあるたびに検証するとなると処理の負荷が上がる可能性があり、署名検証についてはトレードオフな点もあるかと思いますが、最上級の機密事項を扱うシステムについてはセキュリティグループの設定に抜けがあったときに備える手段として検討してみるのはいかがでしょうか?
    なお、ALBが署名したIDトークン(x-amzn-oidc-data)の検証についてはAWSよりaws-jwt-verifyライブラリが提供されています。このライブラリにALBが署名したトークンを検証するためのAlbJwtVerifierクラスが用意されており、公開鍵の取得や署名検証のロジックを自前で書く必要がなく、署名検証を非常にスマートに実装することができるかもしれません。

GitHub - awslabs/aws-jwt-verify: JS library for verifying JWTs signed by Amazon Cognito, and any OIDC-compatible IDP that signs JWTs with RS256, RS384, RS512, ES256, ES384, ES512, Ed25519 and Ed448

JS library for verifying JWTs signed by Amazon Cognito, and any OIDC-compatible IDP that signs JWTs with RS256, RS384, RS512, ES256, ES384, ES512, Ed25519 and Ed448 - awslabs/aws-jwt-verify

github.com

og_img

その他のヘッダー

HTTPリクエストヘッダーを用いた認証に使う物としてx-amzn-oidc-dataを解説しましたので、残り2つを簡単に説明します。

  • x-amzn-oidc-identity
    X-amzn-Oidc-Dataのsubで説明した通り、OneGate上でシステム的に管理されているユーザー識別のIDです。
    OneGateが自動で割り振る値になりますので、Webアプリ上でユーザー識別に使用するのは難しいです。
  • x-amzn-oidc-accesstoken
    IdPから最新のユーザー情報(UserInfo)を取得したり、他のアプリケーションとAPI連携を行ったりするためのトークンです。 「このトークンがあればユーザーになりすまして情報を取得できてしまう」 ため、取り扱いには厳重な注意が必要です。

今回、説明のために検証用のWebサーバー上でtcpdumpを実行し、x-amzn-oidc-accesstokenも含めて値を確認しました。 しかし、本番運用中のシステムでこれを行う際は十分にご注意ください。 パケットキャプチャやWebサーバーのログにアクセストークンを記録してしまうと、それらが漏洩した際にシステムへ多大な影響を与えるリスクがあります。(あくまでも検証環境や開発環境でのみで実施してください。)

認証をオフロードすることのメリット

ここまでHTTPリクエストヘッダーについて解説しました。Webアプリ側にx-amzn-oidc-dataを処理する機構を実装する手間を考えると、一見するとWebアプリケーション側で独自の認証を実装する方が簡単に見えるかもしれません。 しかし、Webアプリ側で認証の仕組みを自作するには、次のような課題が伴います。

  1. セキュリティ実装の責任とリスク
    ログイン機能やセッション管理を自前で実装する場合、脆弱性(セッションハイジャックやクロスサイトスクリプティングなど)を作り込んでしまうリスクが常に伴います。認証ライブラリのアップデート追随など、保守コストも無視できません。
  2. 高度な認証要件への対応の難易度
    「社外からは証明書を持った端末からのみ許可したい」「生体認証を使いたい」「FIDO2を使いたい」といった要件を、個々のWebアプリに実装するのは非常に困難です。

これらの要件をすべて外部のIdPに任せることで、Webアプリケーション側での開発・運用工数削減が見込めます。

高度な認証要件への対応

認証をOneGateへオフロードさせるとOneGateの豊富な認証方法を利用することができます。

  • パスワード認証
  • FIDO2
  • 統合Windows認証
  • Soliton Authenticator
  • ICカード
  • 顔認証

OneGateの認証方法の選択
これらの認証方法を自前で実装するとなると莫大な工数がかかる
これらの認証方式にプラスして、下記のような運用を行うことも可能です。

  • 社内からALBへのアクセスはOneGate認証のみ。社外からALBへのアクセスはクライアント証明書によるmTLS認証+OneGateでの認証
    この設定では、社内にあるデスクトップPCは社外で使用されることがないため、こちらにはユーザーストアへのクライアント証明書展開を省略し、ALBでの認証はOneGate認証のみにします。これにより、証明書運用の負荷を低減させるだけでなく、利用者も証明書提示のストレスから解放されます。 ただセキュリティ面を考えて、社外で使われるノートPCやタブレットにはクライアント証明書を提示させて、証明書が無い管理外端末からのアクセスを拒否させることで、セキュリティを向上させることができます。 OneGateのシステムポリシーで[ネットワーク設定]-[信頼できるネットワークを設定する]に社内からインターネットへの出口のIPアドレスを登録しておき、[アクセス制御設定]を有効にして「信頼できるネットワーク」にチェックを入れることで実現できます。
  • 社外からALBへのアクセスはクライアント証明書によるmTLS認証+OneGateでの認証にプラスしてAuthenticatorやワンタイムパスワード(メール)、顔認証を追加する
    少し過剰かもしれませんが、社外からのアクセス時には上記のクライアント証明書+OneGateの認証にプラスして、ワンタイムパスワード、Soliton Authenticator、顔認証のいずれかを実施させることもできます。
    この設定は上記の設定にプラスして、OneGateのシステムポリシーの[認証設定(利用者ページ)]で「OneGateログイン時に2ステップ認証を行う」を有効にして、「信頼できないネットワークからのアクセス」で「ワンタイムパスワード」を求めるようにしました。 この設定を有効にして社外からのアクセスの動作イメージは次の通りです。
    1. 社外からALBにアクセスすると証明書認証が求められますので、クライアント証明書を提示します。
    2. OneGateの認証を行います。(今回はID、PW認証にしました)
    3. 2ステップ認証の画面が表示されますので、「ワンタイムパスワード送信」をクリックします。
    4. OneGateの利用者に設定されているメールアドレス宛にメールが届きます。
    5. ワンタイムパスワード欄に入力して「OK」をクリックすると、認証に成功してWebアプリにアクセスできます。

最後に

ALBでのOIDC認証連携とOIDC認証したときのクッキーやHTTPアクセスヘッダーに含まれる内容を中心に説明しましたが、改めてALBとOneGateを組み合わせた場合のメリットを説明いたします。

  1. 「端末」と「人」の多要素認証をシームレスに実現
    OneGateの認証時に、OneGateのクライアント証明書で「会社が許可した端末」を特定し、OIDC認証で「正しいユーザー」を確認する。この二重の防御壁を、アプリケーション側に複雑な実装を加えることなく、ネットワークのエッジ(ALB)で実現できる点が最大の強みです。
  2. レガシーアプリのモダナイズ(クラウド移行)を加速
    既存のオンプレミスWebアプリをAWSへ移行する際、認証機能の実装は大きなハードルとなりがちです。しかし、今回解説したHTTPリクエストヘッダー連携を活用すれば、「認証はOneGateとALBに任せて、アプリはヘッダー情報を信頼するだけ」 という疎結合な構成が可能になり、クラウドネイティブ化への移行コストを大幅に下げることができます。
  3. 運用負荷の軽減 証明書の失効が即座に反映される点や、場所や状況に応じた柔軟なポリシー設定は、セキュリティレベルを維持しながら、運用する管理者様の負担を確実に減らします。

セキュリティの高度化と、ユーザーの利便性・運用の効率化の両立。 一見トレードオフになりがちなこれらを両立するソリューションとして、「AWS ALB × Soliton OneGate」 の組み合わせをぜひご検討いただければ幸いです。

記事を書いた人

ソリトンシステムズ ソリューションアーキテクト 小林

ソリトンシステムズで20年以上エンジニア職についておりベテランの域に着きつつありますが、IT業界は目まぐるしく進歩しており、まだまだ修行中です。 うなぎ職人の「串打ち3年、裂き8年、焼き一生」と同じで、IT技術もまた奥深く、一生探求し続ける必要を感じています。 本サイトでは弊社製品の話題を中心にしていますが、弊社製品に限らず色々なことにトライして、皆様の業務、もしくは個人的な興味にちょっとしたヒントをお届けできればと思います。よろしくお願いいたします。