HomeTravel ReportLocal FoodRail&BusAirportMileagemiscAbout Me
TechWiki
Updated : January 2011

Apache2.2 mod_auth_form 2.05

ApacheでForm認証行うための機構であり、ログインしていないユーザが制限されたリソースにアクセスした場合、指定されたログインページに遷移させる。

ログイン情報はセッション管理テーブルとCookieで管理される。

  

ダウンロード

Apache2 Module 'mod_auth_form'
http://comp.uark.edu/~ajarthu/mod_auth_form/

mod_auth_form-2.05-win32.zip(Win32 Binaries)

Apache2.2, MySQL4.1以降に対応している。上記Binaryは、MySQL5.1で稼動確認済み。

データベースの作成

パスワードの管理テーブル、セッション管理テーブルを用意する。

パスワードはMD5でHashした値をセットする。


CREATE DATABASE sampledb;
USE sampledb;
CREATE TABLE passwords(
 uid             VARCHAR (20) PRIMARY KEY,
 password        VARCHAR (32)
);
CREATE TABLE sessions(
 sid     VARCHAR (32) PRIMARY KEY,
 uid     VARCHAR (20)
);
 
GRANT SELECT,INSERT,UPDATE,DELETE ON sampledb.* TO myuser@localhost IDENTIFIED BY 'mypasswd';
FLUSH PRIVILEGES;
 
INSERT INTO passwords values('testuser', '5d9c68c6c50ed3d02a2fcf54f63993b6');

実行例


mysql> CREATE DATABASE sampledb;        データベースの作成
Query OK, 1 row affected (0.06 sec)

mysql> USE sampledb;                    作成したデータベースに切替
Database changed
mysql> CREATE TABLE passwords(          パスワード管理テーブルの作成  
    ->  uid             VARCHAR (20) PRIMARY KEY,
    ->  password        VARCHAR (32)
    -> );
Query OK, 0 rows affected (0.08 sec)

mysql> CREATE TABLE sessions(           セッション管理テーブルの作成 
    ->  sid     VARCHAR (32) PRIMARY KEY,
    ->  uid     VARCHAR (20)
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT SELECT,INSERT,UPDATE,DELETE ON sampledb.* TO myuser@localhost IDENT
IFIED BY 'mypasswd';                    テーブル更新用のMySQLユーザの作成
Query OK, 0 rows affected (0.03 sec)

mysql> FLUSH PRIVILEGES;                権限の反映
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO passwords values('testuser', '5d9c68c6c50ed3d02a2fcf54f63993b
6');                                    実行ユーザをパスワード管理テーブルに登録
Query OK, 1 row affected (0.00 sec)

Apache2.2の設定

zipファイルを展開したディレクトリ中の「mod_auth_form.so」を<Apache>/modulesに入れる。

<Apache>/conf/httpd.confに以下を参考に追加する。


LoadModule auth_form_module modules/mod_auth_form.so

<Directory "C:\www\limited">           #制限をかけるディレクトリを絶対パスで指定
  AuthType Basic
  AuthName "Restricted"
  AuthFormMySQLHost localhost
  AuthFormMySQLPort 3306
  AuthFormMySQLUsername  myuser        #MySQLユーザ名
  AuthFormMySQLPassword mypasswd      #MySQLパスワード  
  AuthFormMySQLDB sampledb      #データベース名
  AuthFormSessionCookies On
  AuthFormLastPageKey referer
  AuthFormPageLogin /login.html   #認証用ログインページ 
  Require valid-user
</Directory>

サンプルコード

以下はドキュメントに記載されているExamplesを動作するよう最低限の編集を加えたものである。

認証用ログインページ(例)

認証のためのユーザID、パスワードを入力する。


<html>
<head>
<title>Login</title>
</head>
<body>
 <form action="/login.php" method="post">
  User ID<input name="uid" type="text" maxlength="20">
  Password<input name="password" type="password" maxlength="20">
  <input type="submit" value="Login">
 </form>
</body>
</html>

認証処理(例)

ログインページから渡されたユーザID、パスワードをパスワード管理テーブルと照合する。

正しい場合は、セッション管理テーブルに登録すると共にCookieに情報を書き出す。


<?php
function genID($seed, $length)
{
 $ID = "";
 srand($seed);
 for($i = 0; $i < $length; $i++)
 {
  $chtype = rand(1, 3);
  switch($chtype)
  {
  case 1: // 0-9
   $ID .= chr(rand(48, 57));
   break;
  case 2: // A-Z
   $ID .= chr(rand(65, 90));
   break;
  case 3: // a-z
   $ID .= chr(rand(97, 122));
   break;
  }
 }
 return $ID;
}
function create_session($mysql, $uid, $password)
{
 //
 // Build list of existing SIDs
 //
 $result = $mysql->query("SELECT sid FROM sessions");
 $num_rows = $result->num_rows;
 while($num_rows > 0)
 {
  $row = $result->fetch_assoc();
  $sids[$row["sid"]] = TRUE;
  $num_rows--;
 }
 $result->close();
 //
 // Generate SID (making sure it is unique)
 //
 $max_attempts = 500000;
 $seed = crc32($password);
 do
 {
  $sid = genID($seed + time(), 32);
  $max_attempts--;
 } while(isset($sids[$sid]) && $max_attempts > 0);
 if($max_attempts <= 0) // NOT GOOD
 return FALSE;
 //
 // Create the session: set the UID and SID in both the client's cookies and
 // the MySQL session table.
 //
 $mysql->query("INSERT INTO sessions (sid, uid) VALUES ('$sid', '$uid')");
 setcookie("uid", $uid, time() + 3600);
 setcookie("sid", $sid, time() + 3600);
 return TRUE;
}
$uid = $_POST["uid"];
$password = $_POST["password"];
$mysql = new mysqli("localhost", "myuser", "mypasswd", "sampledb");
$result = $mysql->query("SELECT password FROM passwords WHERE uid='$uid'");
$row = $result->fetch_assoc();
$real_password = $row["password"];
$result->close();
if(md5($password) == $real_password)
{
 create_session($mysql, $uid, $real_password);
 header("Location: /index.html");
}
else
{
 header("Location: /login.html");
}
$mysql->close();
?>

ログアウトページ(例)

セッション管理テーブルとCookieから情報を削除する。


<?php
$uid = $_COOKIE["uid"];
$sid = $_COOKIE["sid"];
$mysql = new mysqli("localhost", "myuser", "mypasswd", "sampledb");
$mysql->query("DELETE FROM sessions WHERE sid='$sid'");
$mysql->close();
setcookie("uid", $uid, time() - 964224000);
setcookie("sid", $sid, time() - 964224000);
header("Location: /login.html");
?>

Tracking情報

mod_auth_formはオプション機能として、認証されたユーザのアクセス履歴をトラッキング情報としてMySQLのテーブルに保存することができる。
デフォルトでは、ユーザID、URL毎に最新のアクセス情報に更新される形態であるため、オーディットとして使用する場合は、AuthFormMySQLTableTrackingConditionの設定(成立しない条件を指定する)を行うなどの対応が必要である。
(ソースコードの「track_request」関数を参照)

テーブル作成(例)


CREATE TABLE tracking(
  uid               VARCHAR(20),
  client_ip_address VARCHAR(15),
  download_date     DATETIME,
  download_path     VARCHAR(255),
  download_size     INT(8)
);

内容
uid                          ユーザID(名称)
client_ip_address   クライアントのIPアドレス
download_date      ダウンロードされた(アクセスされた)時刻
download_path      ダウンロードされたURL
download_size       ダウンロードサイズ

設定方法(<Apache>/conf/httpd.conf)


AuthFormMySQLTableTracking tracking # トラッキング用テーブル名


Copyright(c) 2012-2013 T.F.T. All rights reserved.