基本認証に失敗したときに別のページにリダイレクトさせる
あるページが基本認証で保護されていて、その認証に失敗したときには別のページにリダイレクトさせたいという要望。
外部からのHTTP接続はApacheで受け付けていて、基本認証で保護されているコンテンツはそのバックエンドであるZopeにあります。
当初はZopeのセキュリティ機構をつかって認証をかけていたんですが、Zope側ではエラー画面をカスタマイズするような機能がない(もしくは簡単ではない)ため、認証をApacheで実施することにしました。
リダイレクトさせるDTMLメソッドをZope側のanonymousで見えるところに置いて、ProxyPassを設定。
Zopeに置いたDTMLメソッドはこんな。
<dtml-call expr="RESPONSE.redirect('http://www.example.com/401_error.html')">
Apache側の設定はこんな感じ。
ProxyPass /dist_contents http://localhost:8080/dist_contents ProxyPassReverse /dist_contents http://localhost:8080/dist_contents ProxyPass /redirect http://localhost:8080/redirect ProxyPassReverse /redirect http://localhost:8080/redirect <Location /dist_contents> AuthType Basic AuthName "test" AuthUserFile conf/.htpasswd Require user valid-user ErrorDocument 401 /redirect </Location>
localhost:8080はZopeが動作しているポートです。
希望する動作としては、以下のとおり。
1)/dist_contents へアクセスする。
2)基本認証画面が表示される。
3)失敗したら(401エラーになったら) /redirect を表示する。
4)localhost:8080/redirect へ Proxy
5)http://www.example.com/401_error.html を表示させる。
ところが、実際に上記設定でやってみると1)の時点でいきなり http://www.example.com/401_error.html がでてきます。
access_logを参照しても、 /dist_contents をgetした時点で401が帰ってきている。うーむ、これは困った。
でも検索していろんな人の例を見ていると、上記のように一旦認証させてから失敗したらErrorDocumentで設定したファイルを返すってことはできているみたい。もしかしたら、Proxyさせるのがいかんのかな。
ということでリダイレクトさせるページをApache側へ設定。
DocumentRootへ以下の内容のファイルをredirect.htmlという名前で設置。
<META HTTP-EQUIV="Refresh" CONTENT="0; URL=http://www.example.com/401_error.html" />
Apache側の設定は以下のとおり。
ProxyPass /dist_contents http://localhost:8080/dist_contents ProxyPassReverse /dist_contents http://localhost:8080/dist_contents <Location /dist_contents> AuthType Basic AuthName "test" AuthUserFile conf/.htpasswd Require user valid-user ErrorDocument 401 /redirect.html </Location>
これでようやく希望する動作を得ることができました。Proxyさせるとそこで一旦401が発生してしまうからなんだろうな。