サマリ | PHPセッションを使った認証プラグイン(CGI版PHPでも実行可) |
---|---|
リビジョン | 0.1 |
対応バージョン | 1.4.7 |
投稿者 | pikky |
投稿日 | 2007-05-10 (木) 00:46:03 |
phpのsessionでは、cookieを使います。また、cookieが使えない場合は、URLにセッション情報が表示されます。いずれの場合も、ユーザ・パスワードが一致しなくても、認証された状態になってしまう危険性が指摘されています。このプラグインでは、とりあえずsession_regenerate_id(TRUE)を入れています。詳しくは、「PHP session 注意」などで検索下さい。
本当にみられたくない場合は、別フォルダにpukiwikiをインストールし、それぞれ.htaccessで管理する方が確実です。お互いにInterWikiで連携して
login.inc.phpは以下のような場合には便利かもしれません。
$auth_type = 'session'; session_start();session_regenerate_id(TRUE);
以下のパッチをpukiwikiのインストールディレクトリからあててください。
% patch -p1 < login-20070511.patch
例えば、
には、pukiwiki.inc.php pukiwiki.ini.phpを以下のようにする。
$auth_users = array( 'authority' => '{x-php-md5}' . md5('hirakedoor'), ); $read_auth = 1; $read_auth_pages = array( '#secret#' => 'authority', ); $edit_auth = 1; $edit_auth_pages = array( '#secret#' => 'authority', );
$auth_type = 'session';session_start();session_regenerate_id(TRUE);を有効にするとsession認証になります。
GPLです。
さくらインターネットで、ユーザ認証を行わなければならなったものの、うまくいかず。さんざんサイトを探して、CGI版PHPではBASIC認証ができないことが判明。かなり落胆・・・。 諦めきれず、pukiwikiでセッション管理をしているサイトがあるはずだと探していたら、以下のサイトで、セッションの使い方とpluginの作り方をみる。ありがとうございました。
それで、pukiwiki1.4.7のauth.phpをみてみたら、認証している部分はbasic_authだけということに気づく。これならいけるじゃん!と改造を決意。basic_authを全部消して実装する。
やってみたらあっさり動いた。
PHPのセッションには問題があるが、「そんなに頑固なセキュリティじゃないけど、編集できないページも作れますよ」と説明できればよいぐらいの立場の人もいるに違いないと思いはじめる。また、たったこれだけの改造で動くようになった、pukiwikiとauth.phpのすばらしさに感謝して、公開することを決意。
元のauth.phpを復活させ、auth_typeで切り替えられるようにし、いくつかのサーバでインストールテスト。公開してみた。
$auth_type = 'session'; session_start();session_regenerate_id();
$auth_type = 'session'; session_start();session_regenerate_id();ではなく、
$auth_type = 'session'; session_start();sessio_regenerate_id();が、出力されました。sessionのnが抜けてました。 -- サイババ 2007-05-10 (木) 14:12:55
// require valid user if ($auth_type == 'session'){ - if (!isset($_SESSION['login_user']) ) { // not login -> login page + if ($auth_flag && !isset($_SESSION['login_user']) ) { // not login -> login page header("Location: " . get_script_uri() . "?plugin=login&referer=" . rawurlencode($page)); } - if ( !PKWK_READONLY && + if ( !PKWK_READONLY && isset($_SESSION['login_user']) && in_array($_SESSION['login_user'], $user_list)) { return TRUE; // Auth success }
<?php ///////////////////////////////////////////////// // login.inc.php // // 2007/5/11 無駄な変数を除いて、分かりやすく変更. get_script_uri()を使用 // htmlspecialcharsをつけた。 // 2007/5/9 オリジナル// ///////////////////////////////////////////////// /* initialize function plugin_login_init() { } */ function plugin_login_inline() { if(isset($_SESSION['login_user'])){ $msg = $_SESSION['login_user']; $msg .= ' <a href="' . get_script_uri() . '?plugin=login">Logout</a>'; } else { $msg = '<a href="' . get_script_uri() . '?plugin=login">Login</a>'; } return $msg; } function plugin_login_convert() { if(isset($_SESSION['login_user'])){ return _get_logout_form(); } return _get_login_form(); } function plugin_login_action() { global $vars, $auth_users; if($vars['pcmd']=='login') { if( isset($vars['pass']) && isset($vars['user']) && isset($auth_users[$vars['user']]) && pkwk_hash_compute($vars['pass'], $auth_users[ $vars['user'] ]) == $auth_users[ $vars['user'] ]) { // login success $_SESSION['login_user'] = $vars['user']; header('Location: ' . get_script_uri() . '?' . rawurlencode( $vars['referer'] ) ); return; } // login fail unset($_SESSION['login_user']); $body = "!!! LOGIN FAILED !!!" . _get_login_form(); } else if($vars['pcmd']=='logout') { $body = ''; if( isset($_SESSION['login_user'])) { $body = htmlspecialchars($_SESSION['login_user']) . " Logout."; unset($_SESSION['login_user']); } $body .= _get_login_form(); } else { if (!isset($_SESSION['login_user']) ) { $body = _get_login_form(); } else { $body = _get_logout_form(); } } return array('msg' => 'login', 'body' => $body); } function _get_login_form(){ global $vars; $script = htmlspecialchars(get_script_uri()); $s_referer= htmlspecialchars($vars['referer']); return <<<EOD <div> <form action="$script" method="post"> <input type="hidden" name="cmd" value="login" /> <input type="hidden" name="pcmd" value="login" /> <input type="hidden" name="referer" value="$s_referer" /> User Name<br /><input type="user" name="user" size="12" /><br /> Password<br /><input type="password" name="pass" size="12" /><br /> <input type="submit" value="login" /> </form> </div> EOD; } function _get_logout_form(){ global $vars; $script = htmlspecialchars(get_script_uri()); $s_referer= htmlspecialchars($vars['referer']); $user = $_SESSION['login_user']; return <<<EOD <div> Current User : $user <form action="$script" method="post"> <input type="hidden" name="cmd" value="login" /> <input type="hidden" name="pcmd" value="logout" /> <input type="hidden" name="referer" value="$s_referer" /> <input type="submit" value="logout" /> </form> </div> EOD; } ?>
diff -urN pukiwiki-1.4.7_notb/lib/auth.php pukiwiki-1.4.7_notb_login/lib/auth.php --- pukiwiki-1.4.7_notb/lib/auth.php 2005-06-13 23:02:07.000000000 +0900 +++ pukiwiki-1.4.7_notb_login/lib/auth.php 2007-05-11 16:02:18.000000000 +0900 @@ -168,7 +168,7 @@ // Basic authentication function basic_auth($page, $auth_flag, $exit_flag, $auth_pages, $title_cannot) { - global $auth_method_type, $auth_users, $_msg_auth; + global $auth_method_type, $auth_users, $_msg_auth, $auth_type; // Checked by: $target_str = ''; @@ -185,43 +185,51 @@ if (empty($user_list)) return TRUE; // No limit - $matches = array(); - if (! isset($_SERVER['PHP_AUTH_USER']) && - ! isset($_SERVER ['PHP_AUTH_PW']) && - isset($_SERVER['HTTP_AUTHORIZATION']) && - preg_match('/^Basic (.*)$/', $_SERVER['HTTP_AUTHORIZATION'], $matches)) - { - - // Basic-auth with $_SERVER['HTTP_AUTHORIZATION'] + // require valid user + if ($auth_type == 'session'){ + if (!isset($_SESSION['login_user']) ) { // not login -> login page + header("Location: " . get_script_uri() . "?plugin=login&referer=" . rawurlencode($page)); + } + if ( !PKWK_READONLY && + in_array($_SESSION['login_user'], $user_list)) + { + return TRUE; // Auth success + } + } else { // $auth_type == 'basic' + $matches = array(); + if (! isset($_SERVER['PHP_AUTH_USER']) && + ! isset($_SERVER ['PHP_AUTH_PW']) && + isset($_SERVER['HTTP_AUTHORIZATION']) && + preg_match('/^Basic (.*)$/', $_SERVER['HTTP_AUTHORIZATION'], $matches)) + { + // Basic-auth with $_SERVER['HTTP_AUTHORIZATION'] list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode($matches[1])); + } + if ( ! PKWK_READONLY && + isset($_SERVER['PHP_AUTH_USER']) && + in_array($_SERVER['PHP_AUTH_USER'], $user_list) && + isset($auth_users[$_SERVER['PHP_AUTH_USER']]) && + pkwk_hash_compute( + $_SERVER['PHP_AUTH_PW'], + $auth_users[$_SERVER['PHP_AUTH_USER']] + ) == $auth_users[$_SERVER['PHP_AUTH_USER']]) + return TRUE; // Auth success } - if (PKWK_READONLY || - ! isset($_SERVER['PHP_AUTH_USER']) || - ! in_array($_SERVER['PHP_AUTH_USER'], $user_list) || - ! isset($auth_users[$_SERVER['PHP_AUTH_USER']]) || - pkwk_hash_compute( - $_SERVER['PHP_AUTH_PW'], - $auth_users[$_SERVER['PHP_AUTH_USER']] - ) !== $auth_users[$_SERVER['PHP_AUTH_USER']]) - { - // Auth failed - pkwk_common_headers(); - if ($auth_flag) { - header('WWW-Authenticate: Basic realm="' . $_msg_auth . '"'); - header('HTTP/1.0 401 Unauthorized'); - } - if ($exit_flag) { - $body = $title = str_replace('$1', - htmlspecialchars(strip_bracket($page)), $title_cannot); - $page = str_replace('$1', make_search($page), $title_cannot); - catbody($title, $page, $body); - exit; - } - return FALSE; - } else { - return TRUE; + // Auth failed + pkwk_common_headers(); + if ($auth_flag && $auth_type !== 'session'){ + header('WWW-Authenticate: Basic realm="' . $_msg_auth . '"'); + header('HTTP/1.0 401 Unauthorized'); + } + if ($exit_flag) { + $body = $title = str_replace('$1', + htmlspecialchars(strip_bracket($page)), $title_cannot); + $page = str_replace('$1', make_search($page), $title_cannot); + catbody($title, $page, $body . '....'); + exit; } + return FALSE; } ?> diff -urN pukiwiki-1.4.7_notb/plugin/login.inc.php pukiwiki-1.4.7_notb_login/plugin/login.inc.php --- pukiwiki-1.4.7_notb/plugin/login.inc.php 1970-01-01 09:00:00.000000000 +0900 +++ pukiwiki-1.4.7_notb_login/plugin/login.inc.php 2007-05-11 16:02:18.000000000 +0900 @@ -0,0 +1,117 @@ +<?php +///////////////////////////////////////////////// +// login.inc.php +// +// 2007/5/11 無駄な変数を除いて、分かりやすく変更. get_script_uri()を使用 +// htmlspecialcharsをつけた。 +// 2007/5/9 オリジナル// +///////////////////////////////////////////////// + + +/* initialize +function plugin_login_init() +{ +} +*/ + +function plugin_login_inline() +{ + if(isset($_SESSION['login_user'])){ + $msg = $_SESSION['login_user']; + $msg .= ' <a href="' . get_script_uri() . '?plugin=login">Logout</a>'; + } else { + $msg = '<a href="' . get_script_uri() . '?plugin=login">Login</a>'; + } + return $msg; +} + + +function plugin_login_convert() +{ + if(isset($_SESSION['login_user'])){ + return _get_logout_form(); + } + return _get_login_form(); +} + +function plugin_login_action() +{ + global $vars, $auth_users; + + if($vars['pcmd']=='login') + { + if( isset($vars['pass']) + && isset($vars['user']) + && isset($auth_users[$vars['user']]) + && pkwk_hash_compute($vars['pass'], $auth_users[ $vars['user'] ]) == $auth_users[ $vars['user'] ]) + { + // login success + $_SESSION['login_user'] = $vars['user']; + header('Location: ' . get_script_uri() . '?' . rawurlencode( $vars['referer'] ) ); + return; + } + // login fail + unset($_SESSION['login_user']); + $body = "!!! LOGIN FAILED !!!" . _get_login_form(); + } + else if($vars['pcmd']=='logout') + { + $body = ''; + if( isset($_SESSION['login_user'])) { + $body = htmlspecialchars($_SESSION['login_user']) . " Logout."; + unset($_SESSION['login_user']); + } + $body .= _get_login_form(); + } + else + { + if (!isset($_SESSION['login_user']) ) { + $body = _get_login_form(); + } else { + $body = _get_logout_form(); + } + } + return array('msg' => 'login', 'body' => $body); +} + +function _get_login_form(){ + global $vars; + $script = htmlspecialchars(get_script_uri()); + $s_referer= htmlspecialchars($vars['referer']); + + return <<<EOD +<div> +<form action="$script" method="post"> + <input type="hidden" name="cmd" value="login" /> + <input type="hidden" name="pcmd" value="login" /> + <input type="hidden" name="referer" value="$s_referer" /> + User Name<br /><input type="user" name="user" size="12" /><br /> + Password<br /><input type="password" name="pass" size="12" /><br /> + <input type="submit" value="login" /> +</form> +</div> +EOD; +} + +function _get_logout_form(){ + global $vars; + $script = htmlspecialchars(get_script_uri()); + $s_referer= htmlspecialchars($vars['referer']); + $user = $_SESSION['login_user']; + + return <<<EOD +<div> +Current User : $user + +<form action="$script" method="post"> + <input type="hidden" name="cmd" value="login" /> + <input type="hidden" name="pcmd" value="logout" /> + <input type="hidden" name="referer" value="$s_referer" /> + <input type="submit" value="logout" /> +</form> +</div> +EOD; +} + + +?> diff -urN pukiwiki-1.4.7_notb/pukiwiki.ini.php pukiwiki-1.4.7_notb_login/pukiwiki.ini.php --- pukiwiki-1.4.7_notb/pukiwiki.ini.php 2006-06-11 23:35:39.000000000 +0900 +++ pukiwiki-1.4.7_notb_login/pukiwiki.ini.php 2007-05-11 14:29:27.000000000 +0900 @@ -241,6 +241,9 @@ ///////////////////////////////////////////////// // Authentication method +//$auth_type = 'basic'; // HTTP authentication (not available in PHP CGI version) +$auth_type = 'session';session_start();session_regenerate_id(TRUE); // PHP SESSION authentication (require login.inc.php plugin) + $auth_method_type = 'pagename'; // By Page name //$auth_method_type = 'contents'; // By Page contents