Skip to content

MS_OAuth20FormPostResponseMode

nishi_74322014 edited this page Sep 1, 2026 · 1 revision

OAuth 2.0 Form Post Response Mode

概要

Redirect エンドポイントへ渡る応答パラメタ群を入れる場所を
制御するためのパラメタとして、response_mode=form_post が追加された。
OpenID Connect の登場により、
この仕様が OAuth 2.0 に追加された)。

response_mode

応答パラメタ群の入る場所
query URL のクエリー部に入る(code
fragment URL のフラグメント部に入る(token
form_post 200 OK + HTTP POST を自動実行する HTML に入る
  • response_mode=form_post は、code で使用すると、
    より安全に、code を Client の Redirect エンドポイントに送信できる。

補足

  • 新規追加されたものは、response_mode=form_post の仕様。
  • response_mode=query, =fragment の仕様は、
    本仕様ではなく、
    OAuth 2.0 Multiple Response Type Encoding Practices
    定義されている。
  • なお、セキュリティ・レベルが下がるため、デフォルトが
    response_mode=fragment / =form_post なものを、
    response_mode=query に変更してはいけない(逆は OK)。

補足(なぜ form_post が安全なのか): 3 つのモードは
**「値がどこに残るか」**が決定的に違う。

モード ブラウザ履歴 Referer ヘッダ サーバのアクセス ログ
query 残る 漏れうる 残る
fragment 残る 漏れない(サーバに送られない) 残らない
form_post 残らない 残らない 残らない(POST ボディ)

URL に載せると、プロキシ・ログ・履歴・Referer といった
意図しない場所に認可コードやトークンが残る。
form_post は POST ボディで渡すため、これらを回避できる。

なお fragment は「サーバに送られない」という利点がある一方、
JavaScript から読めるため、XSS があると抜かれる。
これが Implicit フローが非推奨になった理由の一つでもある
OAuth 2.1を参照)。

詳細

通常、response_mode=form_postresponse_type=code で使用するが、
以下は response_type=id_token で使用したケース。

リクエスト(認可エンドポイント)

GET /authorize?
  response_type=id_token
  &response_mode=form_post
  &client_id=some_client
  &scope=openid
  &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcallback
  &state=DcP7csa3hMlvybERqcieLHrRzKBra
  &nonce=2T1AgaeRTGTMAJyeDMN9IJbgiUG HTTP/1.1
Host: server.example.com

レスポンス(認可エンドポイント)

HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Cache-Control: no-cache, no-store
Pragma: no-cache
<html>
 <head><title>Submit This Form</title></head>
 <body onload="javascript:document.forms[0].submit()">
  <form method="post" action="https://client.example.org/callback">
    <input type="hidden" name="state"
     value="DcP7csa3hMlvybERqcieLHrRzKBra"/>
    <input type="hidden" name="id_token"
     value="eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJzdWIiOiJqb2huIiw..."/>
  </form>
 </body>
</html>

補足(この HTML の要点): onloadsubmit() を呼び、
自動的に POST させるのが仕組みの中核である。

  • JavaScript が無効だと動かない<noscript> に手動送信ボタンを置くのが定石)。
  • 中間の HTML が一瞬表示されるため、
    ユーザーには「白い画面が一瞬出る」ように見えることがある。
  • この HTML 自体に XSS があってはならない(state 等は必ずエスケープ)。

リクエスト(リダイレクト・エンドポイント)

POST /callback HTTP/1.1
Host: client.example.org
Content-Type: application/x-www-form-urlencoded
id_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ...&state=DcP7csa3hMlvybERqcieLHrRzKBra

補足(実装上の注意:SameSite Cookie): form_post
クロスサイトの POST になるため、
Client 側の Cookie(state の照合に使うセッション Cookie など)が
SameSite=Lax では送られない

SameSite クロスサイト POST で送られるか
Strict 送られない
Lax(現在の既定) 送られない(GET のトップレベル遷移のみ許可)
None; Secure 送られる

ブラウザの既定が Lax に変わって以降、
「急に form_post のコールバックでセッションが見つからなくなった」
という事象が起きた。
対象 Cookie を SameSite=None; Secure にする必要がある。
詳細はSameSite属性を参照。

参考

関連仕様


Tags: 移行, IT国際標準, 認証基盤, クレームベース認証, OAuth

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally