auth0とALBを連携させてOpenID Connectを理解したい

auth0とALBを連携させてOpenID Connectを理解したい

2025.10.09

はじめに

こんにちは。コンサルティング部の津谷です。
今回のテーマはOpenID Connect(以下OIDCと略称します)です。前職では、外部のIdPからAWSサービスへのアクセス権限を委任する設定等をやりましたが、解像度はあまり高くなかったです。今回はWebアクセスをする際にApplication Load BalancerでOIDC認証を行い、アクセスを制御してみて解像度上げてみようと思います。

そもそもOIDCとは

https://auth0.com/jp/intro-to-iam/what-is-openid-connect-oidc
auth0の公式ドキュメントで説明されております。
「OpenID Connect または OIDC は、OAuth 2.0の認証・認可メカニズムを採用したアイデンティティプロトコル」を指しています。「OIDCとは」の前に「認証・認可」の概念が根本にあることを理解しておきます。

認証とは「本人確認」を行うといえばすっきりしますね。パスワード認証や、PIN認証、最近だと生体認証(指紋や顔など)でいろいろなサービスにログインしたりすると思います。

認可はある特定のサービス・システムにアクセスしたい場合の権限制御を行う仕組みです。AWSでいうとIAMでロールを付与してAWSリソースへの権限を制御したりしますよね。AWSだけでなく、例えばWindowsのファイルシステムにアクセスできるユーザを絞ったりとか、会社ごとに持っているシステムへの役割別の操作権限を与えたりとかも認可の仕組みです。

auth0で利用する通信規格Oauth2.0は認可を行うものになります。このOauth2.0の規格を認証もできるように拡張したものがOpenID Connectという新しい規格になります。クライアント(アプリケーションやユーザ)が何かのリソースにアクセスしたい場合に、一時的なアクセストークンを払い出してくれます。それと同時に、システムにアクセスしているクライアントが本人確認された情報一式をもっていることを証明してくれるのがIDトークンと呼ばれるものです。これらのトークンを両方払い出してくれるのがauth0のような認証認可を兼任できるサービスになります。

AWSサービスだとCognitoでも実装が可能です。もちろん、IdP(認証管理)はActive Directoryなどを使って、Authorizationサーバ(認可管理)はauth0でやるとかも可能です。
「OpenID Connectとは」を一から解説してくれているブログもあるので、とても参考にしました。ありがとうございます。下記を参考にしつつ、AWSのWeb構成でどういう風に利用するのか1つ1つあてはめながら確認していきます。
https://qiita.com/TakahikoKawasaki/items/498ca08bbfcc341691fe

また、今回の検証をするにあたり下記の構築ブログも非常に参考にしました。ありがとうございます。
https://dev.classmethod.jp/articles/auth0-oidc-alb-auth/

構成

上記を踏まえて、今回の構成に当てはめてみました。
スクリーンショット 2025-10-06 153952
ブラウザから、ALB⇔Lambdaにアクセスする場合を考えております。Lambdaはただ、ログイン成功のHTMLを返すだけの静的ページを実装します。普通にすればインターネット上の誰でもアクセスできるような構成なのですが、ALBでOIDC認証を挟むことでauth0で管理しているユーザでないとアクセスできないように制限をすることが可能です。
1度認証すると、クライアント側が保持するCookies情報を送付するので、以降はTTLに基づいて認証なしでアクセス可能です。

スクリーンショット 2025-10-07 111202
今回はクライアント(アプリケーション)がALBになります。このクライアントから、特定のリソース(Lambda)にアクセスしたいのでauth0で認証・認可を行う必要があります。ユーザがALBにアクセスすると、認証認可済みでないアクセスはauth0へのログイン画面(認可用のエンドポイント)にリダイレクトされるようになっております。

スクリーンショット 2025-10-07 111240
認証情報を入力すると、auth0が情報をIDプールと照合し、問題なければALBに認可コード(リダイレクトURLにcodeパラメータを付与している)を付与して、リダイレクトします。

スクリーンショット 2025-10-07 112401
ALBは認可コードをもらうと、それをauth0のトークンエンドポイントに渡します。

スクリーンショット 2025-10-07 111938
これを提示することでauth0はアクセストークンと一緒にIDトークンをJWT形式で発行してくれます。

スクリーンショット 2025-10-07 112532
ALBは受領したアクセストークンをユーザ情報エンドポイントに送信します。

スクリーンショット 2025-10-07 113114
実際にアクセス要求側のユーザ情報(ユーザ名やEmail情報等)を付与してALBに返します。
ユーザ要求の情報をALBがLambdaにHTTPリクエストにヘッダー(x-amazn-oidc-~)付与した形で転送します。

スクリーンショット 2025-10-07 113731
認証が済んだので、リクエストをそのままLambdaに転送します。問題なければ、ブラウザでアクセス成功の文字列が出力されるはずです。

実装してみた

⓪何よりもまずauth0のライセンスを取得する必要があります。
auth0は22日間の無料トライアルが実施できますので、開始してみましょう。
スクリーンショット 2025-10-06 162645
自分はgithubアカウントとの連携でテナントを作成しました。

①auto0での事前設定を行います。
まずは、ユーザを作成します。
ALBからauth0への認証に使う情報になります。
[ユーザー管理]-[ユーザ]から追加します。
スクリーンショット 2025-10-06 100337
認証方法は「ユーザ名-パスワード」にします。
メールはお使いのもので問題ございません。パスワードも設定しておきます。

次にアプリケーションを作成しましょう。こちらは、auth0に認証認可を行うクライアントであり、ALBのことを指しています。後続で、生成されたアプリケーションのクライアントIDやシークレット情報をALBで設定しますので事前に作成を済ませておきましょう。
スクリーンショット 2025-10-06 100055

②AWS側でネットワーク周りの設定を済ませておきます。

  • VPC
サービス名 リソース名 CIDR 備考
VPC OIDC-test-vpc 10.0.0.0/24
  • サブネット
リソース名 CIDR 備考
OIDC-test-alb-subnet-1a 10.0.0.0/27 ALB用のパブリックサブネット
OIDC-test-alb-subnet-1c 10.0.0.64/27 ALB用の空サブネット
OIDC-test-lambda-subnet 10.0.0.32/28 VPC Lambda用のサブネット
  • ルートテーブル
リソース名 送信先 ターゲット サブネット関連付け
OIDC-test-alb-rt 10.0.0.0/24 local OIDC-test-alb-subnet-1a、OIDC-test-alb-subnet-1c
OIDC-test-alb-rt 0.0.0.0/0 IGW 同上
OIDC-test-lambda-rt 10.0.0.0/24 local OIDC-test-lambda-subnet
  • セキュリティグループ

■ALB(OIDC-test-alb-sg)
インバウンド

タイプ プロトコル ポート範囲 ソース 備考
HTTPS TCP 443 0.0.0.0/0 インターネットからのアクセス

アウトバウンド

タイプ プロトコル ポート範囲 ソース 備考
HTTP TCP 80 OIDC-test-lambda-sg バックエンド(Lambda)へのアクセス
HTTPS TCP 443 0.0.0.0/0 インターネットへのアクセス

Lambda(OIDC-test-lambda-sg)側は特に設定していません。
デフォルトのまま、アウトバウンドはインターネット向けに0.0.0.0/0が空いています。

③Lambdaを作成していきます。
スクリーンショット 2025-10-06 102258
関数名は「OIDC-test-lambda」としました。ランタイムは最新の「Python 3.12」にしています。
実行ロールもデフォルトで付与されるものを利用すれば問題ないです。

スクリーンショット 2025-10-06 102449
VPCは「OIDC-test-vpc」を指定しました。VPCLambdaなので、ENIを「OIDC-test-lambda-subnet」に配置します。セキュリティグループは「OIDC-test-lambda-sg」を指定します。

作成後、コードを貼り付けします。
[コード]タブから、記載します。Webアクセスできることだけ確かめればよいので簡単な応答メッセージのみです。

			
			def lambda_handler(event, context):
return {
    'statusCode': 200,
    'statusDescription': "200 OK",
    'isBase64Encoded': False,
    'headers': {
        'Content-Type': 'text/html; charset=utf-8'
    },

    'body': '<h1>ログイン成功!</h1><p>認証されました。</p>'
}

		

「deploy」を押下し、反映しましょう。

④ALBを作成していきます。
ターゲットグループから行きましょう。
スクリーンショット 2025-10-06 105351
ターゲットタイプは「Lambda関数」を指定しましょう。
ターゲットグループ名は「OIDC-test-targetgroup」にしています。

スクリーンショット 2025-10-06 105400
Lambda関数「OIDC-test-lambda」を指定します。バージョンは最新のもので問題ありません。

本体作っていきます。
スクリーンショット 2025-10-06 105249
名前は「OIDC-test-alb」にしました。スキームは「インターネット向け」にしましょう。
VPCは「OIDC-test-vpc」、サブネットは「OIDC-test-alb-subnet-1a」「OIDC-test-alb-subnet-1c」を指定しています。ALBはマルチAZで構成するので、空サブネットを指定しておきました。

スクリーンショット 2025-10-06 105416
リスナーの設定をしましょう。OIDC認証の設定はリスナーで行うのですが、一旦ポート80でターゲットグループに転送するルールを入れておきます。

⑥HTTPSリスナーを作成するための自己証明書(オレオレ証明書)を作成しておきます。
auth0との認証時の通信プロトコルは全てHTTPSになるため、必要になります。
https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/listener-authenticate-users.html(「ユーザ認証を設定する」を参照)
ACMなどで証明書を発行してもよいのですが、あくまでOIDCの認証が目的なので、ホストゾーンでのドメイン管理までする必要はありません。(本番利用の際はACMでパブリック証明書を発行するか、認証局で発行した正規の証明書をインポートするようにしましょう)

ローカルで発行するので、下記で証明書用のディレクトリを作っておきます。今回Ubuntuを使っていますがopensslコマンドが利用できるOSであればなんでもよいかと思います。

			
			mkdir certification

		

ディレクトリに移動して、秘密鍵を作成します。

			
			openssl genrsa -out ./server.key 2048

		

自己署名用のCSRを作成しておきます。

			
			openssl req -new -key ./server.key -out ./server.csr

		

ここの所有者設定は、任意のもので問題ないので省略します。(一連の流れは後ほど添付します)CN(Common Name)には、ALBのデフォルトDNS名を設定しておきました。(自己署名なのでここも任意で問題ないです)
以下のコマンドで、証明書を発行しましょう。

			
			openssl x509 -in ./server.csr -days 365 -req -signkey ./server.key -out ./server.crt

		

スクリーンショット 2025-10-06 110904
スクリーンショット 2025-10-06 110955

ディレクトリ配下に証明書と秘密鍵があるので、catコマンドで中身を控えておきます。
証明書:server.crt
秘密鍵:server.key

ACMから証明書をインポートしましょう。
スクリーンショット 2025-10-06 111306

sever.crtの内容を「証明書本文」に貼り付けます。
server.keyの内容を「証明書プライベートキー」に貼り付けます。
証明書チェーンは必要ないので空欄のままで問題ないです。「証明書をインポート」を押下して作成しましょう。

⑦リスナーの設定に行く前に、auth0で設定したクライアント情報を抑えておきましょう。
「OIDC-test]-[設定]タブから基本情報を抑えておきます。

  • ドメイン
  • クライアントID
  • クライアントシークレット

スクリーンショット 2025-10-07 094828

【補足】
ドメインはALBがauth0にリダイレクトするURLになります。
クライアントIDはアプリケーションを識別する公開情報で、クライアントシークレットはアプリケーションの正当性を担保するパスワードのようなものになります。

⑧ALBのリスナールールの設定を行います。
スクリーンショット 2025-10-06 111509
先ほどインポートした証明書を指定します。
スクリーンショット 2025-10-06 112110
リスナーのポートは443(HTTPS)を指定します。OIDC認証にチェックを入れ、以下必要な情報を入力します。

デフォルトアクション 項目
アイデンティティプロバイダー OIDC(OpenID Connect)
発行者 auth0で確認した[ドメイン名]
認証エンドポイント [ドメイン名]/authorize
トークンエンドポイント [ドメイン名]/oauth/token
ユーザ情報エンドポイント [ドメイン名]/userinfo
クライアントID auth0で確認したクライアントID
クライアントのシークレット auth0で確認したクライアントシークレット

これらで取得した、トークン情報はセッションCookieに保存されます。
スクリーンショット 2025-10-06 112123
タイムアウトは5分で設定しました。そのほかはデフォルト設定で問題ありません。
スコープ設定は任意です。ただし、ユーザ情報を詳細に取得したい場合などは「profile」を指定したり、今回は短期検証なのでrefresh tokenの取得は行いませんが、トークン更新をする場合は「offline_access」を指定したりする必要があります。デフォルトでopenidは指定されているのでIDトークンの取得は可能です。

⑨構成フローでも説明した通り、ALBはauth0への認証の際にリダイレクトを行いますのでauth0側で認証認可の検証をした後、コールバックするALBのドメインを指定する必要があります。
[OIDC-test]-[設定]タブでアプリケーションのURIから「許可するCallbackURL」を指定しましょう。
スクリーンショット 2025-10-06 113630
「https://(ALBのドメイン)/oauth2/idresponse」と入力します。
Idpアプリでリダイレクトするドメインが公式ドキュメントで指定されています。
https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/listener-authenticate-users.html(「OIDC準拠Idpを使用する準備を整える」を参照)

疎通確認

実際にALBのDNS名でアクセスしてみますと、
スクリーンショット 2025-10-06 113815
auth0の認証画面にリダイレクトされました。設定済みのユーザ情報(ユーザIDとパスワード)を入力していきます。
入力後、ALBのDNSにCallbackされ、ブラウザにログイン成功の文字が出力されました。

疎通の中身

ここまでで、いったん検証は完了なのですが裏でどういう通信が走っているのか確認しておきます。
ブラウザのディベロッパーツールで認証時の通信を見ると、
スクリーンショット 2025-10-07 102049
callbackURLでALBにリダイレクトが成功しています。
パラメータに付与している「code」はLambdaにアクセスするためにALBに認可コードを送付しています。これを引き受けるとクライアントはアクセストークンを取得することができます。アクセストークンはブラウザ側で確認することはできません。

正常にALBのHTTPヘッダーにアクセストークン、IDトークンの情報が渡されているか確認したいので、ブラウザには表示させずCloudWatchに出力させてみました。
スクリーンショット 2025-10-07 103325

x-amzn-oidc-accesstokenはアクセストークンを表しております。こちらはプレーンテキストで渡されているようです。
x-amzn-oidc-identityはIDP側での認証ユーザの識別子を指しています。logsで確認すると、auth0で登録したユーザの「USER ID」と一致しています。こちらもプレーンテキストで渡されています。
x-amzn-oidc-dataはJWT形式で渡されます。確かにユーザ情報なのですが正式にはIDトークンそのものではないようです。公式にも記載がありました。IDトークンがユーザ情報を表す箱とするとクレームは実際の中身とイメージすると腑に落ちました。
https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/listener-authenticate-users.html

下記はCognitoで認証をしていますが、x-amzn-oidc-dataの情報をデコードまでしてくれていますので是非参照ください。
https://dev.classmethod.jp/articles/http-headers-added-by-alb-and-cognito-are-explained/

最後に

今回はALBでOIDC認証を試してみました。認証認可の仕組みを知ること、そのうえでOIDC規格がどういうやり取りをしているのかをつかんだうえで、実践できるとより解像度が上がりますね。ALBは直接OIDC認証ができますが、Cloud Frontなどのエッジサービスを噛ませる場合などは直接の連携ができないので、Lambda@edgeなどを使って認証認可のフローを作りこんだりする必要があります。AWSサービスの特性を理解したうえで、認証設計できるようになりたいと思いました。

この記事をシェアする

FacebookHatena blogX

関連記事