SimpleDetail
📖 3 menit baca

SSO / OAuth2 サーバー機能 — 中央会員管理 & SSO ヘブ

1. ドキュメントの目的

このドキュメントは、Membership Hub が実行する SSO / OAuth2 サーバー機能の仕様を説明します。SSO ヘブは、Identity Provider (IdP) として機能し、SaaS エコシステム内のアプリケーションに認証トークンを発行します。


2. Membership Hub の OAuth2 サーバー機能

Membership Hub は、OAuth2 Authorization Code Flow with PKCE を実装して、認証標準を提供しています。

Hub の役割は次のとおりです。
├── Authorization Server  →  認証コード & トークンを発行
├── Identity Provider     →  メンバーの ID を保存 & 検証
└── Resource Server       →  メンバーのプロフィール & ライセンス情報を提供

各 SaaS アプリケーションは、エコシステムに参加することで、次の役割を担います。

SaaS アプリケーションは次の役割を担います。
└── OAuth2 クライアント (Relying Party)  →  メンバーの behalf でアクセスを要求

3. OAuth2 エンドポイント

3.1 主要エンドポイントの一覧

エンドポイント メソッド 機能
/oauth/authorize GET ログイン & 承認画面を表示
/oauth/token POST 認証コードをトークンに交換
/oauth/token POST リフレッシュトークンを使用してアクセストークンを更新
/oauth/revoke POST トークンを取り消す
/oauth/logout GET Hub のセッションを終了
/oauth/userinfo GET メンバーのプロフィール情報を取得
/.well-known/oauth-authorization-server GET OAuth2 サーバーのメタデータ
/.well-known/jwks.json GET JWT の公開鍵を取得

3.2 /oauth/authorize — 認証エンドポイント

リクエスト:

GET /oauth/authorize
  ?client_id=CLIENT_ID
  &redirect_uri=https://app.noto.com/auth/callback
  &response_type=code
  &scope=profile:read license:read
  &state=RANDOM_CSRF_STATE
  &code_challenge=PKCE_CODE_CHALLENGE
  &code_challenge_method=S256

パラメーター:

パラメーター 必須 説明
client_id はい 登録済みの OAuth2 クライアント ID
redirect_uri はい 登録済みのリダイレクト URI
response_type はい 値が code である必要があります
scope はい 要求するスコープ
state はい CSRF を防ぐためのランダムな値
code_challenge はい (PKCE) code_verifier のハッシュ値
code_challenge_method はい (PKCE) 値が S256 である必要があります

成功レスポンス — リダイレクト先の URI:

https://app.noto.com/auth/callback
  ?code=AUTH_CODE
  &state=RANDOM_CSRF_STATE

失敗レスポンス — エラーを含むリダイレクト先の URI:

https://app.noto.com/auth/callback
  ?error=access_denied
  &error_description=License+not+found
  &state=RANDOM_CSRF_STATE

3.3 /oauth/token — トークンエンドポイント

3.3.1 認証コードをトークンに交換する

リクエスト:

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=AUTH_CODE
&redirect_uri=https://app.noto.com/auth/callback
&client_id=CLIENT_ID
&client_secret=CLIENT_SECRET
&code_verifier=PKCE_CODE_VERIFIER

レスポンス:

{
  "access_token": "eyJhbGciOiJSUzI1NiJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "refresh_token_string",
  "scope": "profile:read license:read"
}

3.3.2 リフレッシュトークンを使用してアクセストークンを更新する

リクエスト:

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token=REFRESH_TOKEN
&client_id=CLIENT_ID
&client_secret=CLIENT_SECRET

レスポンス: トークンを新しく取得した場合と同じです。


3.4 /oauth/userinfo — ユーザー情報エンドポイント

リクエスト:

GET /oauth/userinfo
Authorization: Bearer ACCESS_TOKEN

レスポンス:

{
  "sub": "member_id_123",
  "name": "Budi Santoso",
  "email": "budi@email.com",
  "email_verified": true,
  "picture": null
}

4. JWT アクセストークンの構造

JWT は RS256 (RSA Signature with SHA-256) で署名されています。

4.1 ヘッダー

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

4.2 ペイロード (クレーム)

{
  "sub": "member_id_123",
  "name": "Budi Santoso",
  "email": "budi@email.com",
  "email_verified": true,
  "product": "NTO",
  "license_id": "NTO-A1B2-C3D4-E5F6",
  "tier": "free",
  "license_status": "active_free",
  "expires_at": null,
  "iss": "https://hub.domain.com",
  "aud": "noto-client-id",
  "iat": 1720000000,
  "exp": 1720003600,
  "jti": "unique-token-id"
}

4.3 クレームの説明

クレーム タイプ 説明
sub string メンバーの ID (Subject)
name string メンバーの名前
email string メンバーのメールアドレス
email_verified boolean メールアドレスが検証されているかどうか
product string SaaS の製品コード
license_id string メンバーのライセンス ID
tier string 有効なパッケージ (free, pro, business)
license_status string ライセンスの状態 (active, active_free, grace_period, suspended)
expires_at timestamp / null ライセンスの有効期限 (null = 無期限)
iss string 発行者: Hub の URL
aud string 対象者: SaaS アプリケーションの client_id
iat timestamp トークンが発行された時間 (Issued At)
exp timestamp トークンの有効期限 (Expiry)
jti string トークンの ID (JWT ID)

5. 利用可能なスコープ

スコープ アクセス可能なデータ
profile:read 名前、メールアドレス、プロフィール画像
license:read ライセンス ID、パッケージ、ライセンスの状態、有効期限
openid メンバーの ID (Subject) — OpenID Connect の互換性のために

6. OAuth2 クライアント (SaaS アプリケーション) の登録

エコシステムに参加する各 SaaS アプリケーションは、OAuth2 クライアントとして登録する必要があります。

6.1 必要な情報

フィールド 説明
client_name NOTO アプリケーションの名前
product_code NTO システム内の製品コード
redirect_uris