使用mysql php会话进行LDAP身份验证

时间:2013-06-11 00:55:52

标签: php mysql

我有一个奇怪的问题会话没有保存到全局变量,但他们正确地保存到我的数据库。我有一个ldap auth脚本设置会话,我登录但当我刷新或转到一个不同的页面时,它失去了变量,它驱使我疯了这里是脚本减去ldap_auth.php

<?
function sess_open($save_path, $session_name){
        $_SERVER['SessionDB']->connect();
        if ($_SERVER['SessionDB']->sess) return true;
        else return false;
}

function sess_close(){
        $_SERVER['SessionDB']->disconnect();
}

function sess_read($key){
        global $SESS_LIFE;
        $_SERVER['SessionDB']->Query('UPDATE Sessions SET Expiry="' . (time() + $SESS_LIFE) . '" WHERE SessionID="' . $key . '" AND Expiry >= "' . time() . '"');
        $Value = $_SERVER['SessionDB']->oQuery('SELECT Value FROM Sessions WHERE SessionID = "' . $key . '" AND Expiry >= ' . time());
        if ($Value) return $Value;
        else return '';
}

function sess_write($key, $val){
        global $SESS_LIFE;
        $Expiry = time() + $SESS_LIFE;
        $Value = addslashes($val);
        if (!$qid = $_SERVER['SessionDB']->Query('INSERT INTO Sessions VALUES ("' . $key . '", ' . $Expiry . ', "' . $Value . '")'))
                $qid = $_SERVER['SessionDB']->Query('UPDATE Sessions SET Expiry = ' . $Expiry . ', Value = "' . $Value . '" WHERE SessionID = "' . $key . '" AND Expiry > ' . time());

        return $qid;
}

function sess_destroy($key){
        return $_SERVER['SessionDB']->Query('DELETE FROM Sessions WHERE SessionID = "' . $key . '"');
}

function sess_gc($maxlifetime){
        return $_SERVER['SessionDB']->Query('DELETE FROM Sessions WHERE Expiry < ' . time());
}

$SESS_LIFE = get_cfg_var("session.gc_maxlifetime");
ini_set("session.save_handler", "user");
session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc");

// We want a seperate one in $_SERVER['SessionDB']
$_SERVER['SessionDB'] = new mysql_db();

// Set this information appropriately based on what's in
// our configuration file
$_SERVER['SessionDB']->Hostname = $config->dbHost;
$_SERVER['SessionDB']->Username = $config->dbUser;
$_SERVER['SessionDB']->Password = $config->dbPass;
$_SERVER['SessionDB']->Database = $config->dbName;

session_start();
foreach ($_SESSION as $key=>$value)
        if (is_string($value))
                $_SESSION[$key] = trim($value);

function murder_session(){
//      session_destroy();
//      unset($_SESSION);
}
?>

这是login.php

<?

// check to see if user is logging out
if(isset($_GET['out'])) {
   // destroy session
    session_unset();
    unset($_SESSION['user'],$_SESSION['access']);
    session_destroy();
}

// check to see if login form has been submitted
if(isset($_POST['login_Username'])){
    // run information through authenticator
    if(authenticate($_POST['login_Username'],$_POST['login_Password']))
    {
        // authentication passed

    } else {
        // authentication failed
        $error = 1;
    }
}

// output error to user
if (isset($error)) nice_death("Login failed: Incorrect user name, password, or rights");

// output logout success
if (isset($_GET['out'])) nice_exit("Logout successful");
?>

这是包含文件,其中包含加载顺序

// We prefer to use MySQL for our sessions instead of files in /tmp
// for (somewhat obvious) security reasons. Our functions to handle this
// are in here.
require_once($inc_dir . 'session.inc');

// Let's see if the user is trying to log in. We do this here because
// the login form is displayed on all pages until the user logs in.
require_once($inc_dir . 'ldap_auth.php');
require_once($inc_dir . 'login.inc');

这是ldap脚本

<?
function authenticate($user, $password) {
    // Active Directory server
    $ldap_host = "x.x.x.x";

    // Active Directory DN
    $ldap_dn = "Here is the long LDAP String";

    // Domain, for purposes of constructing $user
    $ldap_usr_dom = "@here.local";

    // connect to active directory
    $ldap = ldap_connect($ldap_host)
        or die("Couldn't connect to LDAP Server");

        $x = explode('.', $user);
        $user = $x[0] . ' ' . $x[1];

    $dn = "cn=".$user.",";

    // verify user and password
    if($bind = @ldap_bind($ldap, $dn . $ldap_dn, $password)) {
        // valid
        // check presence in groups
        $filter = "(cn=" . $user . ")";
        $attr = array("memberof");
        $result = ldap_search($ldap, $ldap_dn, $filter, $attr) or exit("Unable to search LDAP server");
        $entries = ldap_get_entries($ldap, $result);
        ldap_unbind($ldap);


        $_SESSION['user'] = $user;
       // $_SESSION['access'] = $access;
        $_SESSION['LoggedIn'] = true;

        return true;
    } else {
        // invalid name or password
        return false;
    }
}
?>

2 个答案:

答案 0 :(得分:0)

那是因为您的LDAP /登录脚本是在会话脚本和session_start()调用之前启动的,即它获取了LDAP值,它正确地将它们保存到您的数据库并且您的登录工作正常但是因为会话不是开始了,下一个请求会立即忘记放在$_SESSION中的内容。

或者,如果会话没问题,您的会话cookies may be set wrong(到不同的路径或域,或者到期时间太长,或者任何其他错误),但不太可能。

答案 1 :(得分:0)

好的,所以我发现它有点愚蠢,这是我必须这样做的方式,当另一种方式适用于数据库中的用户表。所以这里是旧的,用户表而不是LDAP脚本

function sess_write($key, $val){
        global $SESS_LIFE, $sess_db;
        $Expiry = time() + $SESS_LIFE;
        $Value = addslashes($val);
        if (!$qid = $sess_db->Query('INSERT INTO Sessions VALUES ("' . $key . '", ' . $Expiry . ', "' . $Value . '")'))
                $qid = $sess_db->Query('UPDATE Sessions SET Expiry = ' . $Expiry . ', Value = "' . $Value . '" WHERE SessionID = "' . $key . '"
 AND Expiry > ' . time());

        return $qid;
}

这是我写的新方式

function sess_write($key, $val){
        global $SESS_LIFE, $sess_db;
        $Expiry = time() + $SESS_LIFE;
        $Value = addslashes($val);

        if (!$qid = $sess_db->rQuery('SELECT * FROM Sessions WHERE SessionID = "'.$key.'" AND Expiry >=' . time())) {
                $sess_db->Query('INSERT INTO Sessions (SessionID,Expiry,Value) VALUES ("' . $key . '", ' . $Expiry . ', "' . $Value . '")');
        } else {
                $sess_db->Query('UPDATE Sessions SET Expiry = ' . $Expiry . ', Value = "' . $Value . '" WHERE SessionID = "' . $key . '"');
                if ($sess_db->Error()) die($sess_db->Error());
        }
        return $qid;
}

我仍然不明白为什么一个用户表可以正常使用,但另一种方式适用于两者......