Sessions and LDAP


Sessions and LDAP

我有一个网页。网页的身份验证由我设置的 ldap 服务器处理。现在我不想实现会话,因此当用户处于非活动状态一段时间(在下面的例子中为 10 秒)时,会话将结束,用户将从 ldap 服务器取消绑定。我找到了这段代码摘录:

<?php
    session_cache_expire(20);
    session_start(); 
    $inactive = 10;
    if(isset($_SESSION['start'])) {
        $session_life = time() - $_SESSION['start'];
        if($session_life > $inactive){
            header("Location: endSession.php"); 
        }
    }
    $_SESSION['start'] = time();
?>

它不起作用。如果我刷新页面,它会将我重定向到我的"endSession.php"页面,即使我是活动的。

function check_auth_ldap () {
  $sessionTimeoutSecs = 10;
  $ldapServer = '11.22.33.44';
  $ldapPort = 389;
  if (!isset($_SESSION)) session_start();
  if (!empty($_SESSION['lastactivity']) && $_SESSION['lastactivity'] > time() - $sessionTimeoutSecs && !isset($_GET['logout'])) {
    // Session is already authenticated
    $ds = ldap_connect($ldapServer, $ldapPort);
    if (ldap_bind($ds, $_SESSION['username'], $_SESSION['password'])) {
      $_SESSION['lastactivity'] = time();
      return $ds;
    } else {
      unset($_SESSION['lastactivity'], $_SESSION['username'], $_SESSION['password']);
      header("Location: endSession.php");
      exit;
    }
  } else if (isset($_POST['username'], $_POST['password'])) {
    // Handle login requests
    $ds = ldap_connect($ldapServer, $ldapPort);
    if (ldap_bind($ds, $_POST['username'], $_POST['password'])) {
      // Successful auth
      $_SESSION['lastactivity'] = time();
      $_SESSION['username'] = $_POST['username'];
      $_SESSION['password'] = $_POST['password'];
      return $ds;
    } else {
      // Auth failed
      header("Location: endSession.php");
      exit;
    }
  } else {
    // Session has expired or a logout was requested
    unset($_SESSION['lastactivity'], $_SESSION['username'], $_SESSION['password']);
    header("Location: endSession.php");
    exit;
  }
}

只需在每个受保护页面的顶部调用上述函数即可。这将处理所有身份验证过程。如果用户经过身份验证,它将返回 LDAP 连接资源,如果未进行身份验证,它将重定向到endSession.php

只需将这一行放在每页的顶部:

$ds = check_auth_ldap();

。该功能将为您完成所有跑腿工作。

通常需要基于 uid 的绑定。我稍微修改了函数来实现这一点。用于绑定的 cn 来自基于 UID 的用户名搜索操作。希望这可以帮助某人。

function check_auth_ldap () {
  if (!($_POST['username'] && $_POST['password'])) {
    header("Location: login.php?failure=6");
  }
  $sessionTimeoutSecs = 10;
  $ldapServer = localhost;
  $ldapBaseDN = ou=users,ou=subtree,dc=domain,dc=tld;
  $ldapPort = 389;
  $ldapFilter = "(&(objectClass=*)(uid=".$_POST['username']."))";
  $ldapAttributes = array("cn");
  if (!isset($_SESSION)) session_start();
  if (!empty($_SESSION['lastactivity']) && $_SESSION['lastactivity'] > time() - $sessionTimeoutSecs && !isset($_GET['logout'])) {
    // Session is already authenticated
    $ds = ldap_connect($ldapServer, $ldapPort);
    $sr = ldap_search($ds,$ldapBaseDN,$ldapFilter,$ldapAttributes);
    $result = ldap_get_entries($ds, $sr);
    if ($result) {
        $binddn = $result[0]['dn'];
    } else {
        header("Location: login.php?failure=1");
    }
    ldap_close ($ds);
    $ds = ldap_connect($ldapServer, $ldapPort);
    ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
    if (ldap_bind($ds, $binddn, $_SESSION['password'])) {
      $_SESSION['lastactivity'] = time();
      return $ds;
    } else {
      unset($_SESSION['lastactivity'], $_SESSION['username'], $_SESSION['password']);
      header("Location: login.php?failure=2");
      exit;
    }
  } else if (isset($_POST['username'], $_POST['password'])) {
    // Handle login requests
    $ds = ldap_connect($ldapServer, $ldapPort);
    $sr = ldap_search($ds,$ldapBaseDN,$ldapFilter,$ldapAttributes);
    $result = ldap_get_entries($ds, $sr);
    if ($result) {
        $binddn = $result[0]['dn'];
    } else {
        header("Location: login.php?failure=3");
    }
    ldap_close ($ds);
    $ds = ldap_connect($ldapServer, $ldapPort);
    ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
    if (ldap_bind($ds, $binddn, $_POST['password'])) {
      // Successful auth
      $_SESSION['lastactivity'] = time();
      $_SESSION['username'] = $_POST['username'];
      $_SESSION['password'] = $_POST['password'];
      return $ds;
    } else {
      // Auth failed
      header("Location: login.php?failure=4");
      exit;
    }
  } else {
    // Session has expired or a logout was requested
    unset($_SESSION['lastactivity'], $_SESSION['username'], $_SESSION['password']);
    header("Location: login.php?failure=5");
    exit;
  }
}

我刚刚编写(并测试)了这个:

测试.php

<?php
session_start();
if(isset($_GET['start']))
    $_SESSION['start'] = time();
if(time() - $_SESSION['start'] > 10)
    echo 'Logged out';
else 
    echo 'Logged in';
?>

如果您在浏览器中转到test.php?start,它会说"已登录",然后在浏览器中转到test.php,10 秒后的任何时间,它都会回显"已注销",任何时间少于 10 秒都会显示"已登录"