Kerberos認証(というかmod_auth_kerb)とErrorDocument 401+CGI
さてさて、なんとかWindows Server 2008 R2とADとCentOS 5.7とApache 2.2.3とmod_auth_kerbでKerberos認証を行うところまではいった。後は本番で使うために404や401用の専用ページを作る。Apacheの設定でErrorDocumentディレクティブを用いて独自のエラーページを表示させるわけだ。
ところがである。401のエラーページをCGIにすると、Kerberos認証が効かなくなったのだ。
正確には以下のような状況である。Apacheのけろけろすの設定は
<Location "/needsauth/"> AuthType Kerberos KrbAuthRealms EXAMPLE.COM KrbServiceName HTTP/centos.example.com Krb5Keytab conf.d/centos.keytab KrbMethodNegotiate on KrbMethodK5Passwd on require valid-user </Location>
つまり、Kerberosによる統合Windows認証を試行し、ダメだったらBASIC手順でユーザー名とパスワードを入力させてそいつをKerberosで確認する設定だ。この時に
ErrorDocument 401 /cgi-bin/error401.cgi
というのを同時に指定するとWebブラウザーが統合Windows認証もBASIC手順も行わずにすぐ諦めるようになりくさった。IE8でもFirefox8でも同じだ。例によってWiresharkの出番。すると、http://centos.example.com/needsauthにアクセスした時、ErrorDocumentが無い場合は
WWW-Authenticate: Negotiate\r\n WWW-Authenticate: Basic realm="hogehoge"\r\n
と、WWW-AuthenticateというHTTPレスポンスヘッダーを2行で返すが、ErrorDocumentにCGIを設定した場合は
WWW-Authenticate: Negotiate, Basic realm="hogehoge"
と、カンマ区切りで2つ並べて返している。httpd.confで
ErrorDocument "hogehoge"
という風に文言だけ返すようにした場合と、
ErrorDocument /error/error404.html
という風に静的HTMLを返すようにした場合は起こらない。CGIが悪さをしていると思われる。より正確に言うとCGIが結果をApacheに返した後、Apache(mod_cgi?)がHTTPレスポンスヘッダーを再構築するタイミングでこの意図しないHTTPレスポンスヘッダーのマージが行われているようだ。ApacheのソースとAPRのソースを見てみたがよく分からんかった。apr_table_tというのでヘッダーを管理しているようだが。
なので、mod_auth_kerbが統合Windows認証とBASIC手順によるユーザー名の取得を両方とも有効にしていて、かつ401のエラードキュメントをCGIに転送している場合にのみ発生すると結論付けた。今回構築中のこれは本番ではBASIC手順によるユーザー名の取得は行わないため、これ以上の調査は面倒だし断念する事と相成った。
追記:上を書いた後こんな事(mod_auth_kerb+401CGI)しとる奴居らんやろ~ネットで散々っぱら探しても全く見当たらんしわしが世界で最初ちゃうんバグ報告なんかしちゃったら「おうおうJapのくせにやるじゃねえか」とか言われるんやろうかうひひひひひ、と意気揚々とApache HTTPDのBugzillaに登録しに行ったらすでにあった・・・・。ASF Bugzilla – Bug 50891(2.2.16用の様だが)パッチまで用意されとるがね。ただ、今回の件に限って言えば要らんし独自にパッチを当てたプログラムを動かした時に問題が起きたら責任取れんし何もせん事に決定。