OBO認証
概要
ログイン済みユーザー情報を、複数のサービス間で安全に共有する仕組み
On-Behalf-Of の略
主に EntraID を使ったログインでよく用いられるフロー
認証フロー図
以下の例は API A 経由で API Bへ問い合わせ位をしたいときに、用いられるフロー図
⑦の処理で API A が IdP 側に、API B のアクセスすためのトークンを取得して、後続のタスク API A が API B を叩くということを実現している。
code:mermaid
sequenceDiagram
autonumber
actor User as ユーザー
participant Client as クライアントアプリ
participant IdP as IdP(認可サーバー)
participant A as API A(中継)
participant B as API B(最終)
Note over User,IdP: ── フェーズ1:ユーザー認証 ──
User->>Client: アプリにアクセス
Client->>IdP: 認証リクエスト(Authorization Code + PKCE 等)
IdP->>User: ログイン画面を表示
User->>IdP: 資格情報を入力(ID/PW, MFA等)
IdP-->>Client: トークンA を発行
Note over Client,B: ── フェーズ2:OBO フロー ──
Client->>A: トークンAを付けてリクエスト
activate A
A->>IdP: OBOリクエスト<br/>(トークンA + client_id + client_secret)
activate IdP
IdP-->>A: トークンBを返却
deactivate IdP
A->>B: トークンBを付けてリクエスト
activate B
B-->>A: 処理結果を返却
deactivate B
A-->>Client: 最終結果を返却
deactivate A
Client->>User: 結果を表示
上記のパターンでいう⑦のやり取りに関しては、通常のClient CredentialパターンとOBOパターンの違いを見ていく
Client Crendential
OBO認証の違いは、②で受け取る値に sub が API A 自身の情報を含んでいる点
API B にリクエストするときには、実際にクライアントがどのユーザーがリクエストしたかが判別できなくなっている
code:mermaid
sequenceDiagram
autonumber
participant IdP as IdP(認可サーバー)
participant A as API A(中継)
participant B as API B(最終)
Note over A,B: ── Client Credentials フロー ──
A->>IdP: POST /token<br/>grant_type=client_credentials<br/>client_id=API-A<br/>client_secret=xxxxx<br/>scope=api://API-B/.default
Note right of IdP: ユーザー情報なしで発行
IdP-->>A: トークンC 発行<br/>sub: API-AのサービスID(アプリ自身)<br/>aud: api://API-B<br/>roles: "Data.Read"(アプリロール)<br/>※ユーザー情報なし A->>B: トークンCを付けてリクエスト
activate B
Note right of B: sub = API A(アプリ自身)<br/>→ ユーザーが誰かわからない<br/>→ アプリロール(roles)で認可判定
B-->>A: 処理結果を返却
deactivate B
OBO
OBO認証では②で返されるトークンの sub がクライアント側で認証が完了したユーザー情報が格納されている
また、scp でユーザーが操作できるスコープが入るので、認証・認可情報を API B に伝搬することができる
code:mermaid
sequenceDiagram
autonumber
participant IdP as IdP(認可サーバー)
participant A as API A(中継)
participant B as API B(最終)
Note over A,B: ── OBO フロー ──
A->>IdP: POST /token<br/>grant_type=jwt-bearer<br/>assertion={ユーザーのトークンA}<br/>client_id=API-A<br/>client_secret=xxxxx<br/>scope=api://API-B/.default<br/>requested_token_use=on_behalf_of
Note right of IdP: ユーザー情報を引き継いで発行
IdP-->>A: トークンB 発行<br/>sub: user@example.com(ユーザー本人)<br/>aud: api://API-B<br/>scp: Files.Read(委任スコープ)
A->>B: トークンBを付けてリクエスト
activate B
Note right of B: sub = ユーザー本人<br/>→ ユーザー単位の認可が可能<br/>→ 委任スコープ(scp)で認可判定
B-->>A: 処理結果を返却
deactivate B