rhaco3で作ったWebサービス全体にBasic認証をかけた時にちょっとハマったのでメモ。

症状

rhaco3の認証が入っているサービスで全体にBasic認証をかけると、

  1. トップページに入る時にBasic認証がかかる
  2. 認証完了
  3. ログインページに移動
  4. またBasic認証がかかる

というケースが見られました。Webサーバにはnginxを使いました。

原因

nginx側の設定が悪いのかなとか色々試行錯誤しましたが、結論としてrhaco3の認証部分が401のレスポンスを吐いてたのが問題でした。

Basic認証の動作というページで詳しく書かれています(以下に引用します)が

  1. ユーザーがクライアント(IE等のWebブラウザ)に目的のURLを入力する。
  2. クライアントが、Authorization: ヘッダを付加しないで、 目的のコンテンツにアクセスする。
  3. サーバーは、401 Authorization Required のレスポンスを返して、 クライアントに認証が必要である旨を伝える。
  4. クライアントがユーザーに ID/PW の入力を求める (IE等のブラウザが、ポップアップウインドウを出して、  ID/PW の入力をユーザーに求めるアレです。)
  5. ユーザーが ID/PW を入力する。
  6. クライアントが、Authorization: ヘッダに ID/PW の情報を付加 して目的のコンテンツに再度アクセスする。
  7. サーバが ID/PW を解析して、認証OKであればコンテンツをクライ アントに返す。
  8. クライアントがコンテンツを表示して、ユーザーがそれを閲覧する。
        +------+  1--->  +--------+  2--->  +-------+
        |      |  <---4  |        |  <---3  |       |
        | User |         | Client |         | httpd |
        |      |  5--->  |        |  6--->  |       |
        +------+  <---8  +--------+  <---7  +-------+

(コンテンツデータを1つ取得するために、リクエスト・レスポンスの  やりとりが2回行われています。)

なお、 Authorization: ヘッダには、 Basic認証の ID と PW とを :(半角のコロン)でつなげた文字列を、 base64した値が格納さています。 (例えば、  Authorization: Basic dXNlcjAxOnBhc3N3b3JkCg== といったようになります。)

ように、Basic認証ではサーバが401のレスポンスを返すことで、ブラウザ側にポップアップを出させているようです。その為rhaco3の認証部分で401のレスポンスを出した時に認証の情報がリセットされてしまったのではないかと思われます。

対処

rhaco3の認証部分(\org\rhaco\flow\parts\RequestFlow::do_login)で401を送信していた部分で200を送信することで対処できました。

rhaco3で見られた症状でしたが、他のフレームワークでも特に何も考えてなかったら引っかかる可能性があります。というかBasic認証とフレームワークの認証両方掛けるとか普通無いですよねそうですよね。