iOS10 Safariでの401レスポンス時の仕様変更にハマった
iOS10が公開されましたね。 毎年のことですが、Safariの仕様変更には何かしら影響を受けていて楽しいです。
今年も例のごとく、見事にサービス影響がありました!
401レスポンス時に予期しないBasic認証が出てくるケースがある
401 Unauthorizedなレスポンスの時にBasic認証が出てくるパターンが有ることを発見。
試しに検証環境を作ってみてどんなパターンがそれに当てはまるのか検証してみました。
すると下のような結果に
WWW-Authenticate header pattern | result in iOS9 | result in iOS10 |
---|---|---|
- | 401 response | 401 response |
Basic realm="simple" | requires basic auth | requires basic auth |
OAuth realm="..." | 401 response | requires basic auth |
Bearer realm="token_required" (with out Authorization header request) | 401 response | 401 response |
Bearer error="invalid_token" | 401 response | 401 response |
Bearer realm="token_required", OAuth realm="..." (with out Authorization header request) | requires basic auth | requires basic auth |
Bearer error="invalid_token", OAuth realm="..." | requires basic auth | requires basic auth |
Hoge realm="..." | 401 response | 401 response |
登録済みのauth-schemeごとの検証、独自定義のものの検証を行ってみたのですが、どうもiOS10からはOAuthを使った認証のレスポンスで401を返すと(WWW-AuthenticateヘッダにOAuthがついたもの)Basic認証のダイアログが出てくることが分かりました。
自分の知識不足で起きてる問題な気もするのですが、事象の再現だけで終わって根本的な原因究明まではできず、暫定対応として 400
として返す対応をしました(トークン切れですしおすし)。ただやはりiOS10でのみ再現するので「なんだかなぁ」という気持ちです。(仕様上ヘッダに2つ以上のchallenge*を含んでよい仕様なので含めてみたらそっちでもBasic認証が問われたが、なぜだかは引き続き勉強中です。)
Twitterで探してみた
safari は CORS でリクエストして WWW-Authenticate が戻ってくる 401 の場合だけ、 XHR でもダイアログが出てしまうらしい所まで分かった。しかし、これは一体。。
— Jxck (@Jxck_) 2015年3月3日
どうも以前はCORSのXHRで発生していたことがわかりました。しかし、コレは一体。。。
参考
challenge = auth-scheme [ 1*SP ( token68 / #auth-param ) ]
- RFC 7235 - Hypertext Transfer Protocol (HTTP/1.1) Authentication
- Hypertext Transfer Protocol (HTTP) Authentication Scheme Registry
- RFC 5849 - The OAuth 1.0 Protocol