15
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

初学者がKeycloakを使って認可コードフローの流れをブラウザから見てみた

Last updated at Posted at 2025-12-08

初めに・この記事の概要

記事をご覧いただきありがとうございます。
本記事では、認証・認可に関連する OpenID Connect(OIDC) の流れや認可コードフローについて、実際のリクエスト単位で整理します。自身が初学者として学習を進める中でなかなかイメージをつかみづらかったこともあり、具体的な通信内容・画面例を交えながら紹介してみたいと思います。

想定読者

私自身が初学者であることからも、本記事は以下のような読者の方を想定しています。

  • 認証技術について学び始めた方
  • OIDC認可コードフローの具体的な処理の流れを実際に目で見て確認したい方

OpenID Connect (OIDC)の概要

OIDCとは

OpenID Connect(OIDC)は、OAuth 2.0 を拡張した認証連携のためのプロトコルです。
「認証」とは、そのユーザーアカウントへのアクセスが、そのユーザーアカウントを持つ正しい相手からのアクセスかどうかを検証し、その結果を返却することです(当人認証)。
「認証連携」とはあるユーザーが認証されたという情報を、他のサービスやシステムに伝達することで、それを安全にやり取りする方法を標準化したものの一つに、OIDCがあります(他にも、SAMLなどがあります)。

認可コードフロー

OIDCのフローにはいくつか種類がありますが、本記事では、特にセキュアである認可コードフローをテーマにその流れをブラウザから見てみたいと思います。認可コードフローは、クライアントID・クライアントシークレットという情報を安全に保存することができるアプリケーションに適したフローです。

認可コードフローの流れ

以下は登場人物とOIDCにおける用語の対応と、認可コードフローの流れを示すシーケンス図です。

登場人物とOIDCにおける用語の対応

登場人物 OIDCでの用語
ユーザー
(ブラウザ)
User Agent
(End-User)
認証サーバー OpenID Provider(OP)
アプリケーション Relying Party(RP)

※OIDCの仕様ではUser Agent(End-User)ですが、本記事ではユーザー(ブラウザ)と表記します

シーケンス図

環境構築

本記事では、こちらの書籍に従った認証連携を実装しており、RPとしてSpring Bootによるクライアントアプリ、OPとしてKeycloakを使用します。
詳細な実装内容は6.2節Spring Securityを用いた認証連携に記載されています。

認証と認可 Keycloak入門 第2版 OAuth/OpenID Connectに準拠したAPI認可とシングルサインオンの実現(リックテレコム)
中村雄一、和田広之、田村広平、田畑義之、青柳隆、渡辺竜二、奥浦航、相田洋志 著
https://www.ric.co.jp/book/development/detail/2081

クライアントアプリをKeycloakと連携した際の構成は下記の構成図のようになります。

image.png

Keycloakの構築

動作環境

  • Keycloakバージョン:26.3.3
  • Javaランタイム:OpenJDK 21.0.8
  • デプロイ環境:Windows Subsystem for Linux 2 (WSL2)
    (本検証では ローカルホストのWSL2上でKeycloakを動作させています)

Keycloakの設定

  • クライアント設定
    Keycloakの管理コンソール画面のClients>Create Clientsから以下の設定を行いました。
    image.png
    image.png
    image.png

設定項目、設定値は以下です。

設定項目 概要 設定値
Client type 認証プロトコルをプルダウンで選択。 OpenID Connect
Client ID クライアントを識別するためのID。 springboot-oidc
Client authentication クライアントタイプを選択するボタン。Onだとコンフィデンシャルクライアント、Offだとパブリッククライアントとなる。 On
Valid redirect URIs 認証レスポンスでリダイレクト可能なURL。 http://localhost:8180/login/oauth2/code/keycloak
Valid post logout redirect URIs ログアウト後にリダイレクト可能なURL。 http://localhost:8180/user-area
  • ユーザー設定
    OP(Keycloak)との認証連携後、ログインを実行するためのユーザーを管理コンソール画面のUsers>Add userから作成します。

image.png

設定項目、設定値は以下です。

設定項目 概要 設定値
Username ユーザー名 user001
Email ユーザーのメールアドレス user001@example.com
First name user
Last name 001

クライアントアプリの構築

動作環境

  • デプロイ環境:WSL2(Keycloakサーバーと同一のWSL2上で動作)

利用アプリ

下記のGitHubリポジトリをクローンし、ソースのビルド、およびSpring Bootアプリケーションを起動しています。
https://github.com/keycloak-book-jp/keycloak-book-jp-v2/tree/main/06-02/sso/springboot-oidc

今回はサーバー間通信を見るため、ログの出力設定に変更を加えています。
具体的には、クライアントアプリのapplication.propertiesファイルに以下を追記しました。

# アプリケーションのログをファイルに出力する設定
logging.file.name=myapp.log
# Spring Securityの全般的なログレベルをTRACEに設定
logging.level.org.springframework.security=TRACE
# OAuth2クライアント関連のログレベルをTRACEに設定
logging.level.org.springframework.security.oauth2=TRACE

認可コードフローの流れをリクエスト単位でみよう!

使用したブラウザ

  • Microsoft Edge for Business
    • バージョン 139.0.3405.111 (公式ビルド) (64 ビット)

開発者ツールによるリクエストの確認方法

ブラウザ(ユーザー)とサーバー間のリクエストを見るために開発者ツール(F12キーまたはCtrl+Shift+I)を開き、Networkタブを表示します。

image.png

開発者ツールを表示した状態でWebページにアクセスすると、そのページを表示するまでに生じたリクエストのリストが1行1リクエストの単位で表示されます。リクエストは上から下に時系列順で表示されます。
このツールを使って認可コードフローの各手順に該当するリクエストを探し、詳細を見ていきたいと思います。

【ユーザー操作手順1】認証連携設定済みのRP(クライアントアプリ)にアクセス

まずブラウザを起動します。そして、アドレスバーにアクセスしたいRP(クライアントアプリ)上のURL(http://localhost:8180/user-area)を入力し、Enterを押します。

image.png
そうすると、ログイン画面が表示されます。
image.png

認可コードフローを参照すると、以下のようなやり取りがブラウザ・RP
(クライアントアプリ)・OP(Keycloak)間で行われていることが分かります。

それでは、まず、ログイン画面を表示するに至るまでのやり取りを認可コードフローの手順に沿ってリクエスト単位で追ってみましょう。

1.Webアプリケーションにアクセス

まず、1番上に位置する、最初に生じるhttp://localhost:8180/user-areaへのリクエストの詳細を確認します。
image.png

リクエストを選択すると、3つのタブがあり、それぞれ以下の情報が載っています。
image.png

タブ表示名 概要
General 選択したHTTPリクエストの「基本情報・全体の概要」が表示される。
Response Headers サーバーが返した「HTTPレスポンスヘッダー」が表示される。
Request Headers ブラウザがサーバーに送った「HTTPリクエストヘッダー」が表示される。

このリクエストについてGeneralタブと、その応答であるResponse Headersの詳細を確認します。
ここから、http://localhost:8180/user-areaのレスポンスにLocationヘッダーが設定されており、http://localhost:8180/oauth2/authorization/keycloakへリダイレクトが生じていることがわかります。

image.png

今回使用しているRP(クライアントアプリ)の仕様上URLアクセス後、http://localhost:8180/oauth2/authorization/keycloakにリダイレクトして認可コードフローを開始します。

指定されたリダイレクト先(http://localhost:8180/oauth2/authorization/keycloak)へのリクエスト詳細を、Generalタブと、Response Headersタブから確認します。
image.png

すると、今回もリダイレクトが発生しており、リダイレクト先はOP(Keycloak)の認可エンドポイント(http://localhost:8080/realms/demo/protocol/openid-connect/auth)が指定されています。
このリダイレクトが、認可コードフローでの「2.認証リクエストを送信」に該当します。

OP(Keycloak)の認可エンドポイントは管理コンソール画面のRealm Setting>EndpointsOpenID Endpoint Configurationのリンクから確認できます。
image.png

image.png

「認証リクエスト」を送信する先である「認可エンドポイント」はOP(Keycloak)を使用した場合以下のような形式で指定されます。
http://[ホスト名]:[ポート]/realms/[レルム名]/protocol/openid-connect/auth

2.認証リクエストを送信

http://localhost:8180/oauth2/authorization/keycloakへアクセスし、発生したリダイレクトを受けて、次に発生するhttp://localhost:8080/realms/demo/protocol/openid-connect/authへのリクエストが、「2.認証リクエストを送信」に該当します。
image.png

ここで、Request URLをよく見てみると、URLの後ろにクエリパラメータがいくつか設定されていることがわかります。
まず、見やすいように改行しました。

http://localhost:8080/realms/demo/protocol/openid-connect/auth?
response_type=code&
client_id=springboot-oidc&
scope=openid&
state=mn_LzkEAIxmnFJm_Go7zqzfb2h8zZZYOHCcv0BbUst4%3D&
redirect_uri=http://localhost:8180/login/oauth2/code/keycloak&
nonce=R1K2pqgZTrRGxHsMPPc4OiogWyDV2JvNzYNh8b-J9fU

認可エンドポイントのURLには、全部で5つのクエリパラメータが設定されていました。

パラメータ名 概要
response_type 認証フローの種類を指定します。
認可コードフローの場合はcodeを指定します。
code
client_id OP(Keycloak)に登録済のクライアントの識別子。
OP(Keycloak)の管理コンソールから設定することができます。
springboot-oidc
scope アクセストークンに関連付けたいスコープ。OIDCの場合、認証リクエスト時にopenidをセットすることが必須。 openid
state クライアントが生成した一意の文字列。
セッションと関連付けて保持することでCSRF対策などに利用される値。
mn_LzkEAIxmnFJm_Go7zqzfb2h8zZZYOHCcv0BbUst4%3D
redirect_uri OIDCのリダイレクトURI。Spring SecurityのOAuth 2.0 Loginを利用してRPをOIDCに対応させる場合、/login/oauth2/code/[プロバイダー名]という形式となる 。 http://localhost:8180/login/oauth2/code/keycloak
nonce クライアントが生成した一意の文字列。
セッションと関連付けて保持することでリプレイ攻撃対策などに利用される。
R1K2pqgZTrRGxHsMPPc4OiogWyDV2JvNzYNh8b-J9fU

3.ログイン画面の表示

OP(Keycloak)はブラウザからの認証リクエストを受け取ると、ユーザーが未認証の場合ログイン画面を返却します。
ということは、先ほどのhttp://localhost:8080/realms/demo/protocol/openid-connect/authからのレスポンスが「3.ログイン画面の表示」にあたります。

image.png

【ユーザー操作手順2】 Username/Passwordを入力しSign Inをクリックし、ログイン

表示されたログイン画面で、今回のデモ用に作成したユーザー情報を入力し、Sign Inをクリックします。
image.png

すると、もともとアクセスを試みていたhttp://localhost:8180/user-areaのページが表示されました。
image.png

認可コードフローの視点から見ると、ログイン操作を実行し、認証が完了して画面が表示されるまでは以下のようなやり取りが発生しているはずです。

引き続き、認可コードフローの手順に沿って、RP(クライアントアプリ)のリソースが表示されるまでの通信内容を追ってみましょう。

4.ログイン操作

ログイン画面でテスト用ユーザーIDとパスワードを入力し、ログイン操作を実行します。
この時、最初に送信されるhttp://localhost:8080/realms/demo/login-actions/authenticateへのリクエストについて詳細を確認します。

image.png

Request MethodがPOSTになっており、フォームに入力したユーザー情報がPOSTメソッドで送信されていることがわかります。
今回の設定では、このリクエストを送信するエンドポイントにおいて、KeycloakがユーザーID・PWを使った認証処理を行っています。認証処理については、OIDCの仕様範囲外です。そのため、設定されているパラメータはKeycloak独自に設定されたものとなります。各パラメータの概要については下記のとおりです。

パラメータ名 概要
session_code 認証セッションを示す一意なコード。OP側でこのセッションに紐づく状態を管理するために用いられる。 OGZq4rpnijlc7lfr7nf1ZxPRT7_cE3mpugCt3sM4zYc
execution 現在の認証フロー内で実行中のexecutionのID。executionとは、Keycloakにおける認証処理の実行単位のことです。 a417350-5baf-435c-bd0b-8b0350ce124b
tab_id ブラウザのタブを識別するための一意のID。 mqOdWrxsn5Q
client_data tab_idclient_idなどの認証リクエスト送信時の情報をBase64エンコードした文字列。 eyJydSI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODEMC9sb2dpbi9vYXV0aDIvY29kZS9rZXljbG9haylsInJ0IjoiY29kZSIsInN0ljoibW5fTHprRUFJeG1uRkptX0dvN3pxemZiMmg4elpaWU9IQ2N2MEJIVXNONEOifQ

5.認証レスポンス

「4.ログイン操作」の手順で発生したhttp://localhost:8080/realms/demo/login-actions/authenticateリクエストのレスポンスが、「5.認証レスポンス」に該当します。
image.png

その後、「5.認証レスポンス」は「2.認証リクエストを送信」で設定したredirect_urihttp://localhost:8180/login/oauth2/code/keycloak)にリダイレクトされています。
image.png

このリダイレクトのクエリパラメータについて確認してみましょう。

http://localhost:8180/login/oauth2/code/keycloak?
state=mn_LzkEAIxmnFJm_Go7zqzfb2h8zZZYOHCcv0BbUst4%3D&
session_state=668b4767-5dbf-490f-9d96-fd91002aa9e1&
iss=http%3A%2F%2Flocalhost%3A8080%2Frealms%2Fdemo&
code=df519269-d169-4180-a3b6-571e431f60b0.668b4767-5dbf-490f-9d96-fd91002aa9e1.01f0dc5b-8345-4f66-9e9f-b13b9ae3862c
パラメータ名 概要
state クライアントが生成した一意の文字列。
セッションと関連付けて保持することでCSRF対策などに利用される値。
「2.認証リクエストを送信」のstateパラメータと同一である必要がある。
fo4TJAkoOR4WJxIaC2ct5PtDA9BhB4RU3zhP2XR5KrE%3D
session_state OP(Keycloak)がセッション管理のために用いるパラメータ。 668b4767-5dbf-490f-9d96-fd91002aa9e1
iss 認証レスポンスを発行したOP(Keycloak)の識別子を表すパラメータ。 http%3A%2F%2Flocalhost%3A8080%2Frealms%2Fdemo
code OP(Keycloak)の発行した認可コード。 df519269-d169-4180-a3b6-571e431f60b0.668b4767-5dbf-490f-9d96-fd91002aa9e1.01f0dc5b-8345-4f66-9e9f-b13b9ae3862c

issパラメータは管理コンソール画面のRealm Setting > EndpointsのOpenID Endpoint Configurationから確認できるissureの値と同じです。
image.png

次の2ステップはRP(クライアントアプリ)とOP(Keycloak)間での通信になります。
トークンの中身はRPの外に出してはいけないため、RP・OP間のみのやり取りとなっており、ブラウザからは詳細を閲覧することができません。

今回はRPのログから以下のステップに該当するリクエスト・レスポンスを確認します。

6.トークンリクエスト

RPのログから抜粋した、OPへのトークンリクエストです。
OpenID Endpoint Configurationにも載っているトークンエンドポイントにPOSTリクエストをおくっていることが確認できました。

2025-11-18T19:35:14.467+09:00 DEBUG 3493 --- [springboot-oidc] [http-nio-8180-exec-3] o.s.web.client.RestTemplate              : HTTP POST http://localhost:8080/realms/demo/protocol/openid-connect/token

7.トークンレスポンス

上記の「6.トークンリクエスト」のログで確認されたスレッド名である [http-nio-8180-exec-3]に着目し、ログを確認すると、
ログメッセージ Response 200 OKが出力されており、リクエストが成功していることが確認できました。

2025-11-18T19:35:14.579+09:00 DEBUG 3493 --- [springboot-oidc] [http-nio-8180-exec-3] o.s.web.client.RestTemplate              : Response 200 OK

8.コンテンツ返却

http://localhost:8180/user-areaへリダイレクト後、Status Codeから正常にコンテンツが返却されていることがわかります。

image.png

終わりに

実際に詳細を見ての感想

今回は認可コードフローをリクエスト単位で見ることで、OIDCの仕様で定められたやり取りと、OIDCの仕様範囲外でのやり取り(Keycloak・クライアントアプリそれぞれの仕様)の両方が混在していることがわかりました。
そこに気付くまで認証リクエストとアプリの仕様によるリクエストを混同してしまっていました。
今後、より複雑な構成のシステムに携わることもあるかと思うので、より正確で深い理解ができるよう勉強していきたいと思います。

今後に向けてのコメント

本記事では1つのRP(クライアントアプリ)が存在する構成でしたが、今後は複数RP(クライアントアプリ)の存在する構成でのSSOの実現や多要素認証などにも挑戦してみたいです。

参考

15
1
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
15
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?