OAuth 2.0とOpenID Connectの仕組み:認可と認証の基礎

OAuth 2.0の認可フローとOpenID Connectの認証レイヤーを図解とともに解説し、アクセストークン・IDトークンの仕組みとセキュリティ上の注意点を紹介します。

はじめに

Webアプリケーションにおいて、ユーザーの認証(Authentication: 本人確認)と認可(Authorization: 権限付与)は最も重要なセキュリティ機能です。

  • 認証: 「あなたは誰ですか?」→ ユーザーの身元を確認する
  • 認可: 「あなたは何ができますか?」→ リソースへのアクセス権限を制御する

OAuth 2.0は認可のためのフレームワーク、**OpenID Connect(OIDC)**はOAuth 2.0の上に構築された認証レイヤーです。本記事では、それぞれの仕組みとセキュリティ上の注意点を解説します。

OAuth 2.0の概要

4つの役割

OAuth 2.0では4つの役割(ロール)が定義されています。

役割説明
Resource Ownerリソースの所有者エンドユーザー
ClientリソースにアクセスするアプリWebアプリ、モバイルアプリ
Authorization Serverトークンを発行するサーバーGoogle、Auth0
Resource Server保護されたリソースを提供API サーバー

クライアント登録

OAuthを利用するには、事前にAuthorization Serverにクライアントを登録し、以下の情報を取得します。

  • client_id: クライアントの識別子(公開情報)
  • client_secret: クライアントの秘密鍵(機密、サーバーサイドのみ)
  • redirect_uri: 認可後のリダイレクト先URL

OAuth 2.0のグラントタイプ

Authorization Code Grant(認可コードグラント)

Webアプリケーションで最も一般的なフローです。

1. Client → Authorization Server: 認可リクエスト
   GET /authorize?response_type=code
     &client_id=CLIENT_ID
     &redirect_uri=REDIRECT_URI
     &scope=read write
     &state=RANDOM_STATE

2. Resource Owner: ログイン&同意

3. Authorization Server → Client: 認可コード返却
   302 Redirect to REDIRECT_URI?code=AUTH_CODE&state=RANDOM_STATE

4. Client → Authorization Server: トークン交換(バックチャネル)
   POST /token
     grant_type=authorization_code
     &code=AUTH_CODE
     &redirect_uri=REDIRECT_URI
     &client_id=CLIENT_ID
     &client_secret=CLIENT_SECRET

5. Authorization Server → Client: アクセストークン返却
   { "access_token": "...", "token_type": "bearer", "expires_in": 3600 }

Authorization Code + PKCE

SPA(Single Page Application)やモバイルアプリでは client_secret を安全に保持できないため、**PKCE(Proof Key for Code Exchange)**を使用します。

  1. クライアントがランダムな code_verifier を生成
  2. code_challenge = BASE64URL(SHA256(code_verifier)) を計算
  3. 認可リクエストに code_challenge を含める
  4. トークン交換時に code_verifier を送信
  5. Authorization Serverが code_verifier から code_challenge を再計算して検証

これにより、認可コードを傍受されてもトークン交換ができなくなります。

Client Credentials Grant

サーバー間通信(Machine-to-Machine)で使用されます。ユーザーは介在しません。

POST /token
  grant_type=client_credentials
  &client_id=CLIENT_ID
  &client_secret=CLIENT_SECRET
  &scope=api:read

非推奨のグラントタイプ

  • Implicit Grant: トークンがURLフラグメントで返されるため、漏洩リスクが高い。PKCEの登場により非推奨
  • Resource Owner Password Credentials: ユーザーのパスワードをクライアントに直接渡すため、セキュリティ上の問題が多い

アクセストークンとリフレッシュトークン

アクセストークン

APIリクエスト時に Authorization ヘッダーで送信するBearerトークンです。

GET /api/resource
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
  • 有効期限: 通常15分〜1時間と短く設定
  • スコープ: アクセスできるリソースの範囲を制限

リフレッシュトークン

アクセストークンの有効期限が切れた際に、ユーザーの再認証なしで新しいアクセストークンを取得するために使います。

POST /token
  grant_type=refresh_token
  &refresh_token=REFRESH_TOKEN
  &client_id=CLIENT_ID

OpenID Connect(OIDC)

OIDCとは

OIDCはOAuth 2.0の上に構築された認証レイヤーです。OAuth 2.0が「何にアクセスできるか」を扱うのに対し、OIDCは「誰であるか」を扱います。

認可リクエストに scope=openid を含めることで、OIDCフローが有効になります。

IDトークン(JWT)

OIDCでは、アクセストークンに加えてIDトークンが発行されます。IDトークンはJSON Web Token(JWT)形式で、以下の3部分から構成されます。

Header.Payload.Signature

Header:

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "key-id-123"
}

Payload(標準クレーム):

クレーム説明
subユーザーの一意識別子"user-123"
issトークン発行者"https://auth.example.com"
aud対象クライアント"client-id"
exp有効期限(UNIX時刻)1709942400
iat発行時刻1709938800
nameユーザー名"Taro Yamada"
emailメールアドレス"taro@example.com"

Signature: Header + Payload を秘密鍵で署名し、改ざんを検出します。

UserInfoエンドポイント

アクセストークンを使って追加のユーザー情報を取得できます。

GET /userinfo
Authorization: Bearer ACCESS_TOKEN

セキュリティ上の注意点

stateパラメータ(CSRF対策)

認可リクエストにランダムな state 値を含め、リダイレクト時に一致を検証します。これによりCSRF攻撃を防止します。

PKCEの必須化

OAuth 2.1ではすべてのクライアントタイプでPKCEが必須となる見込みです。新規実装ではPKCEを必ず使用してください。

トークンの保管

クライアント種別推奨保管場所注意点
サーバーサイドWebアプリサーバーのセッションHttpOnly Cookieで参照
SPAメモリ内(変数)localStorageは非推奨(XSSリスク)
モバイルアプリOS提供のセキュアストレージKeychain / Keystore

redirect_uriの検証

Authorization Serverは、事前に登録された redirect_uri と完全一致するかを検証する必要があります。ワイルドカードや部分一致を許可すると、オープンリダイレクト攻撃のリスクがあります。

まとめ

項目OAuth 2.0OpenID Connect
目的認可(リソースアクセス制御)認証(ユーザー身元確認)
主要トークンアクセストークンIDトークン(JWT)
スコープread, writeopenid, profile, email
用途API保護SSO、ログイン

関連記事

参考文献