このページの目次

OAuth2 と OpenID Connect

OAuth2は認可フレームワーク(アプリにあなたの代わりにリソースへのアクセスを許可する)であり、OIDCはその上に認証レイヤーを追加して(アプリにあなたの身元を確認させる)、authorization code + PKCEが現在の実践であり、implicit flowは廃止されました。

概要

OAuth2(RFC 6749, 2012)はインターネットにおける認可の標準フレームワークです。「サードパーティのアプリにリソースへのアクセスを許可するが、パスワードは共有しない」。中核となるのは Authorization Code + PKCE フローです。ブラウザが認可サーバーにリダイレクト → ユーザーがログイン → ブラウザが code を持って戻る → クライアントが code を使って access token を取得します。OIDC(OpenID Connect, 2014)は OAuth2 に ID 認証(id_token)を追加し、「Google/GitHub でログイン」の基盤となっています。JWT は OAuth2 で最も一般的な access token の形式です。自己完結型、検証可能、ステートレスです。

OAuth2: 認可(認証ではない)

4つの役割:
  Resource Owner: ユーザー
  Client: サードパーティ アプリ
  Authorization Server: 認可サーバー
  Resource Server: API サーバー

Authorization Code + PKCE (Web フローで唯一推奨される方法):
  1. Client: code_verifier(ランダム)を生成し、code_challenge = SHA256(verifier) を計算
  2. ブラウザのリダイレクト:
     GET /authorize?response_type=code
       &client_id=grafana
       &redirect_uri=https://grafana.example.com/login/callback
       &scope=openid profile email
       &state=random123
       &code_challenge=<base64url(challenge)>
       &code_challenge_method=S256
  3. ユーザーのログインと同意
  4. ブラウザのリダイレクト: https://grafana.example.com/login/callback?code=AUTH_CODE&state=random123
  5. Client → Authorization Server (バックチャネル):
     POST /token
     grant_type=authorization_code
     &code=AUTH_CODE
     &redirect_uri=...
     &code_verifier=<verifier>  ← サーバーは SHA256(verifier)==challenge を検証
  6. レスポンス: { "access_token", "refresh_token", "id_token", "token_type":"Bearer", "expires_in":3600 }
  7. Client: access_token を使って API にリクエスト (Authorization: Bearer <token>)

PKCE が必要な理由

従来のフローでは code が傍受される可能性があります(モバイル アプリの redirect URI が他のアプリによって登録される可能性があるため)。PKCE を使用すると、code が漏洩しても、code_verifier がなければ token を取得できません。

JWT

形式: base64(header).base64(payload).signature

Header: {"alg":"RS256","typ":"JWT","kid":"key-2025"}
Payload (claims):
  iss: 発行者
  sub: ユーザー ID (subject)
  aud: 受信者 (audience, この token の対象者)
  exp: 有効期限 (unix)
  iat: 発行時刻
  email, name, groups: カスタム claims

Signature: RSA-SHA256(base64(header)+"."+base64(payload))

検証:
  1. JWKS を取得 (https://auth.example.com/.well-known/jwks.json) → kid に対応する公開鍵を取得
  2. 署名を検証
  3. exp(期限切れでないか)、aud(この token が自分宛てか)、iss(信頼できる発行者か)を確認

OpenID Connect (OIDC)

OIDC = OAuth2 + ユーザー ID (id_token):

id_token (JWT): クライアントに対して「ユーザーは誰か」を証明する(API を呼び出すために使用されるものではない)
access_token:   API に対して「クライアントがアクセス権を持っている」ことを証明する(ユーザー情報は含まれない)

Client Credentials(マシン間)

POST /token
  grant_type=client_credentials
  &client_id=my-app
  &client_secret=secret

→ { "access_token":"...", "expires_in":3600 }
→ ユーザーの関与なし

参考

  • jwt.io: JWT のデバッグ
  • Keycloak: オープンソースの ID プロバイダー
  • OIDC playground: openidconnect.net

キーワード: OAuth2, PKCE, JWT, OIDC, id_token, client credentials, JWKS, Keycloak