407はプロキシへの認証を求める応答です。401は接続先リソースへの認証を求めます。一つのリクエストで両方に遭遇することもあるため、パスワードを渡す前に誰が要求しているのかを確認してください。

ステータスと認証チャレンジのヘッダーを比べる

応答チャレンジヘッダー資格情報ヘッダー認証に関わる相手
407 Proxy Authentication RequiredProxy-AuthenticateProxy-Authorization中継するプロキシ
401 UnauthorizedWWW-AuthenticateAuthorizationオリジンリソースの認証フロー

ステータスは重要な最初の手掛かりですが、やり取り全体を確認します。ページ本文に407と表示されていても、実際のHTTP 407応答と同じではありません。同様に、独自のログインページは200を返しながら、アプリケーション層での認証を求める場合があります。

HTTPSリクエストがサイト到達前に407で失敗する理由

通常のHTTPプロキシでHTTPSリクエストを送る際、クライアントは一般にまずCONNECTトンネルの確立を求めます。プロキシはこのCONNECTリクエストに認証を要求できます。認証が完了していなければ、トンネルを通じた接続先とのTLSセッションはまだ確立されていません。そのため、サイトのAPIトークンを変えても、この段階の問題は直りそうにありません。

詳細出力付きのリクエストで、認証要求が現れる位置を確認します。

curl --noproxy '' --proxy http://127.0.0.1:8080 --connect-timeout 5 --max-time 15 --verbose https://example.com/

ローカルの待受アドレスを利用するものに置き換え、ログで最初の認証要求を読みます。CONNECT中の407は接続先とのTLSより前です。トンネルが正常に確立された後で401が現れることもあります。

プロキシ用インターフェースから資格情報を渡す

信頼する管理者から提供された接続先とアカウントなら、curlはプロキシ認証方式をネゴシエートし、未指定のパスワードを対話入力で求められます。

curl --proxy http://proxy.example:8080 --proxy-anyauth --proxy-user alice https://example.com/

例の接続先とユーザー名を、利用を許可されたサービスの情報に置き換えてください。ユーザー名だけを指定すれば、上のコマンドにパスワードを直接書かずに済みます。対応する認証方式はcurlのビルドやプロキシによって異なります。ネゴシエーションに失敗したら、実際のチャレンジとビルドの対応機能を確認します。

プロキシ認証のオプションは、curlのオリジンユーザー認証用オプションとは別です。プロキシの認証要求に対して、オリジン用のAuthorizationヘッダーを代わりに追加しないでください。プロキシの資格情報ヘッダーを無関係なリクエストへ手動で転送したり、アプリケーション全体で使い回すヘッダーに保存したりすることも避けます。

プロキシが407を返し続けるとき

  • 想定したプロキシのホストとポートを使っているか確認します。
  • Basicと決めつけず、プロキシが提示する認証方式を確認します。
  • アカウントの状態と、サービスが特定のユーザー名形式を求めるかを確認します。
  • 資格情報をURLに埋め込む場合は、特殊文字の渡し方を確認します。
  • ブラウザー統合型の企業認証に、ランタイムやプラットフォーム側の対応が必要かを調べます。
  • クライアント側の情報だけでは足りない場合は、機密情報を除いたリクエスト識別子やサーバーログの記録を管理者に依頼します。

ログインが成功していても、403やCONNECTの拒否はアクセス方針による判断かもしれません。パスワードを何度試しても、禁止された接続先への権限は得られません。

接続先のHTTPSがすべてのプロキシ認証を守るわけではない

プロキシ認証は接続先とのTLS確立前に行われることがあります。プロキシ自体への接続が平文で、認証方式がそのリンク上に再利用可能な資格情報を露出させる場合、接続先がHTTPSでも、そのやり取りを後から保護することはできません。サービスに適した通信方式と認証の組み合わせを選び、未知の公開プロキシへ個人のアカウントを送らないでください。

詳細ログは共有する前に見直します。ツールが一般的な資格情報フィールドを隠しても、ユーザー名、内部の接続先名、Cookie、そのほか識別につながる情報が残る場合があります。

関連記事