Web制作・開発会社 プレスマンのスタッフブログ

PRESSMAN*Tech

mod_auth_formを使ってベーシック認証

その昔、mod_auth_formについて書いたことがありました
今回は、これでなくて、apache2.4から実装されたmod_auth_formを触ってみました。
ベーシック認証で問題無いんだけど、ブラウザ内のフォームで認証してみたいということは、見た目や印象の問題で多少なりとも要望があったりします。それをapacheだけで実装してしまおうという機能です。最近nginxなどのapache以外のブラウザがシェアを伸ばしていますが、apacheだってmpm_eventがあるし、リバースプロキシだってできるし、fcgi_proxyだって使えるし、なにしろ、apacheだし!
今回のmod_auth_formでのベーシック認証は、そんなに難しいはなしでなくて、cookie使ってベーシック認証してしまおうということです。


aws上でAmazon Linuxを使ってサーバーを立てて実験してみました。
必要なモジュールはApacheのドキュメントに書いてあります。
Amazon Linuxでは下記のパッケージをインストールすれば動作します。また、下記の上から2つだけ動作はしますが、3つめのパッケージを入れないとmod_session_cryptoが使えず、ID、パスワードがcookie上に生データのまま保存されてしまいます。

yum install httpd24
yum install mod24_session
yum install apr-util-openssl

インストールしたままだと、mod_requestとmod_session_cryptoが有効になっていないので有効にして下さい。
Amazon Linux上だとそれぞれ、/etc/httpd/conf.modules.d/00-base.conf/etc/httpd/conf.modules.d/01-session.confで設定されています。

mod_auth_formを使用するサイトを「http://authform.pressman.ne.jp」とします。当然実運用はhttpsで行うべきです。ページ構成は下記の通りです。認証に失敗した場合はログインページに戻るようにします。

  • ログインページ:http://authform.pressman.ne.jp/login.html
  • 認証実行:http://authform.pressman.ne.jp/dologin.html
  • 認証が必要なディレクトリ:http://authform.pressman.ne.jp/auth/
  • 認証成功ページ:http://authform.pressman.ne.jp/auth/index.html
  • ログアウト実行:http://authform.pressman.ne.jp/dologout.html

Apacheの設定はこんな感じです。

<VirtualHost *:80>
    DocumentRoot "/var/www/html"
    ServerName authform.pressman.ne.jp
    <Directory "/var/www/html/auth">
        require valid-user 
        AuthFormProvider file
        AuthUserFile /var/www/passwd
        AuthType form
        AuthName realm
        AuthFormLoginRequiredLocation http://%{SERVER_NAME}/login.html
        Session On
        SessionCookieName auth_form path=/
        SessionCryptoPassphrase iymLrU1xWyAcJOv035PC0Gd
    </Directory>
    <Location /dologin.html>
        SetHandler form-login-handler
        AuthFormLoginRequiredLocation http://%{SERVER_NAME}/login.html
        AuthFormLoginSuccessLocation http://%{SERVER_NAME}/auth/index.html
        AuthFormProvider file
        AuthUserFile /var/www/passwd
        AuthType form
        AuthName realm
        Session On
        SessionCookieName auth_form path=/
        SessionCryptoPassphrase iymLrU1xWyAcJOv035PC0Gd
    </Location>
    <Location /dologout.html>
        SetHandler form-logout-handler
        AuthFormLogoutLocation http://%{SERVER_NAME}/loggedout.html
        Session On
        SessionMaxAge 1
        SessionCookieName auth_form path=/
        SessionCryptoPassphrase iymLrU1xWyAcJOv035PC0Gd
    </Location>
</VirtualHost>

/authのディレクトリの制限自体はAuthType formになるくらいで普通のベーシック認証と変わりません。
AuthFormLoginRequiredLocationでログインしていない場合に移動するページを指定します。普通はログインするページだと思います。
Session Onでセッションを有効にして、SessionCookieNameでセッション情報を保存するcookieの名前と有効範囲を設定します。この場合auth_formという名前で、サイト全体で有効にしています。
SessionCryptoPassphraseはcookie上の情報を暗号化するためにつかうパスフレーズです。これを設定しないとcookie上にID,パスワードがそのまま保存されてしまいます。

ログイン実行、ログアウト実行はそれぞれdologin.html,dologout.htmlですがどちらも実際に存在するページでは無く、apache上でLocationディレクティブを使用して作った実行用のページです。それぞれ、上記の設定を見れば大体わかると思います。

あとは、必要はhtmlページを作成するだけです。
/login.html

<!doctype html>
<html>
<body>
  <form method="POST" action="/dologin.html">
    Username: <input type="text" name="httpd_username" value="" />
    Password: <input type="password" name="httpd_password" value="" />
    <input type="submit" name="login" value="Login" />
  </form>
</body>
</html>

/loggedout.html

<!doctype html>
<html>
<body>
  ログアウトしました。
  <br>
  <a href="login.html">ログイン</a>
</body>
</html>

/auth/index.html

<!DOCTYPE html>
<html>
<body>
  <h3>ログイン成功</h3>
  <a href="/dologout.html">ログアウト</a>
</body>
</html>

これで、問題無く動きました。画像の制限にベーシック認証は使いやすいので、プログラムと組み合わせて使えればいいのですが、それはまた検証が必要ですね。