君たちは永遠にそいつらより若い

技術と音楽と日々のこと。

AndroidDownloadManager にBasic認証などの認証情報が受け継がれずファイル保存が失敗する



テスト中の Web サイトは、IP 制限なり、Basic 認証なり、cookie 認証なり、何らかの認証をかけてコンテンツを保護するものです。そこで発生する Android の悲劇の回避方法の一つを紹介。

状況

  • サイトにIP 制限、Basic 認証、cookie 認証などをかけている
  • 何故か Android だけファイル(画像, pdf, zip etc...)の閲覧・保存・ダウンロード時に認証を通り抜けられずダウンロードに失敗しましたと表示される
  • 画像を表示した後の、画像を保存リンク先を保存 を押下した際にも発生
  • 元の拡張子を無視して.bin という拡張子で保存されることもある
  • PC, Android, iPhone 共に、ページ・画像・js, css類は認証を通過している
  • Android でも機種やブラウザ(標準ブラウザ or Chrome)によって通り抜けたり、通り抜けられなかったり

原因

  • Android は、ブラウザとファイルのダウンロードのプロセスが別(の場合がある)
  • ブラウザがアクセスした後、バックグラウンドで AndroidDownloadManager がダウンロード処理を行っている(場合がある)
  • 故に、認証情報を受け継ぐことが出来ていない
  • アクセスログを確認すると UserAgent が AndroidDownloadManager になっている

解決方法(回避方法)

  • Content-Disposition: attachment; ヘッダを出して、添付ファイルとしてダウンロードさせる
  • すると AndroidDownloadManager に処理を移譲せずに、ブラウザ自体がファイルをダウンロードするので、認証情報が受け継がれ、認証を通り抜けられる
  • 一見、ダウンロードマネージャと同じような動作をするが、実際にアクセスログの UserAgent を確認すると、ブラウザの UserAgent として来ている!
  • 結果表示は、機種やブラウザによって様々。ダウンロードされたり、そのまま表示されたり。

私が確認した端末たちで成功しただけなので、まだまだ海のように広い Android 界には例外端末があるかもしれませぬ。

参考資料

Xperia SO-01BのQ&Aページ(端末の公式サイトなので、きっちりした方への説明へオススメ★)

Android Chrome browser unnecessarily renames names & types of downloaded files

Android and the HTTP download file headers

Android 4.0系端末でダウンロードするときのUser Agent