通过 PHP 使用 LDAP 发现嵌套组
Discovering nested groups using LDAP with PHP
我有一个 LDAP 身份验证系统,可以从 AD 中查找和检索 memberOf 属性,但我不确定如何获取嵌套组成员身份。我知道 memberOf:1.2.840.113556.1.4.1941: 扩展,但不确定如何使其适应我的代码。我的工作代码在下面(它只是不做嵌套组)。有经验的人可以帮忙吗?
输入CONFIG.PHP
$adbase = "some.domain.com";
$adtree = "OU=All Departments,DC=some,DC=domain,DC=com";
$group_admins = "Test App Admins";
$group_staff = "Test App Staff";
在RUN.PHP
function extract_unit($string, $start, $end) {
$pos = stripos($string, $start);
$str = substr($string, $pos);
$str_two = substr($str, strlen($start));
$second_pos = stripos($str_two, $end);
$str_three = substr($str_two, 0, $second_pos);
$unit = trim($str_three); // remove whitespaces
return $unit;
}
extract($_POST);
if($action == "logon") {
$ldap = ldap_connect($adbase);
$userID = "$user@$adbase";
$bind = @ldap_bind($ldap, $userID, $pass);
if($bind == true) {
// assign session variables
$_SESSION['username'] = $user;
// get group memberships
$results = ldap_search($ldap, $adtree, "(samaccountname=$user)",array("memberof", "mail"));
$entries = ldap_get_entries($ldap, $results);
// get group count (first entry) and group listings
$beat = 0; $str = ""; foreach($entries[0]['memberof'] as $temp) {
if($beat == 0) {
$count = $temp;
}
else {
$temp = extract_unit($temp, "CN=", ",OU=");
$str .= "$temp, ";
$groups[] = $temp;
}
$beat++;
}
// return the mail address, whosebug.com/questions/16224720/searching-for-email-address-ldap-active-directory
$mail = $entries[0]["mail"][0];
// assign session variables
$_SESSION['mail'] = $mail;
// groups defined in config.php
$client = "You are logged in as a client.";
if(in_array($group_admins, $groups)) {
$_SESSION['admin'] = true;
$client = "You are logged in as an administrator.";
}
else {
$_SESSION['admin'] = false;
}
// groups defined in config.php
if(in_array($group_staff, $groups)) {
$_SESSION['staff'] = true;
$client = "You are logged in as staff.";
}
else {
$_SESSION['staff'] = false;
}
// if it returns true user was found
print "<h2>Signed in as $user</h2>\n";
print "$client<br>\n";
print "<img src=\"./images/next.png\"> <a href=\"./?d=welcome\">Continue ...</a>\n";
print "<!-- count is $count -->";
print "<!-- groups are $str -->";
print "<!-- mail is $mail -->";
}
else {
print "<h2>Login attempt failed</h2>\n";
print "<img src=\"./images/logon.png\"> <a href=\"./?d=user/logon\">You may try again ...</a>\n";
}
}
您需要使用类似于以下的可扩展匹配过滤器语法构建查询:
(memberOf:1.2.840.113556.1.4.1941:=CN=GroupOne,OU=安全组,OU=组,DC=YOURDOMAIN,DC=NET)
哪个RESOLVES ALL MEMBERS (INCLUDING NESTED) SECURITY GROUPS (REQUIRES AT LEAST WINDOWS 2003 SP2)
我终于开始工作了,但我不得不走另一条路。
这是我最终 PHP LDAP 身份验证工作的代码,带有嵌套组。
这假定正在检查用户名以查看它是否存在于组或嵌套组中。如果你取出 (samaccountname=$user) 那么它将 return 该组中所有用户的列表,但它会花费相当长的时间(不到一秒到 30+ 秒)。
/*
$adBase like "some.domain.com"
$ldBase like "OU=Users,DC=some,DC=domain,DC=com"
$admins like "CN=Test Admins,OU=Groups"
$staff like "CN=Test Staff,OU=Groups"
$ldaplink like "ldap://ldap.domain.com/o=domain.com??sub?"
*/
$ldap = ldap_connect($adBase);
$bind = @ldap_bind($ldap, "$user@$adBase", $pass);
$admins = $ldAdmin.",".$ldBase;
$staffs = $ldStaff.",".$ldBase;
$filtrA = "(&(objectClass=user)(samaccountname=$user)(memberof:1.2.840.113556.1.4.1941:=$admins))";
$filtrS = "(&(objectClass=user)(samaccountname=$user)(memberof:1.2.840.113556.1.4.1941:=$staffs))";
if($bind) {
// default message if not found in either group
$client = "You are logged in as a client.";
// get basic info first; whosebug.com/questions/1622472...
$result = ldap_search($ldap, $ldBase, "(samaccountname=$user)", array("mail"));
$entries = ldap_get_entries($ldap, $result);
$mail = $entries[0]["mail"][0];
$_SESSION['username'] = $user;
$_SESSION['mail'] = $mail;
#region check admin/nested group
$link1A = ldap_search($ldap, $ldBase, $filtrA, array("name"));
$link2A = ldap_get_entries($ldap, $link1A);
@$nameA = $link2A[0]["name"][0]; // throws error if not defined but that's what we're testing thus the @
if($nameA == true) {
// user was found in administrators or in nested group
$_SESSION['admin'] = true;
$client = "You are logged in as an administrator.";
}
else {
$_SESSION['admin'] = false;
}
#endregion
#region check staff/nested group
$link1S = ldap_search($ldap, $ldBase, $filtrS, array("name"));
$link2S = ldap_get_entries($ldap, $link1S);
@$nameS = $link2S[0]["name"][0]; // throws error if not defined but that's what we're testing thus the @
if($nameS == true) {
// user was found in staff or in nested group
$_SESSION['staff'] = true;
$client = "You are logged in as staff.";
}
else {
$_SESSION['staff'] = false;
}
#endregion
// if it returns true user was found
print "<h2>Signed in as $user</h2>\n";
print "$client<br>\n";
print "<img src=\"./images/next.png\"> <a href=\"./?d=tem/welcome\">Continue ...</a>\n";
print "<!-- mail is $mail -->";
}
else {
print "<h2>Login attempt failed</h2>\n";
print "<img src=\"./images/logon.png\"> <a href=\"./?d=user/logon\">You may try again ...</a>\n";
}
我有一个 LDAP 身份验证系统,可以从 AD 中查找和检索 memberOf 属性,但我不确定如何获取嵌套组成员身份。我知道 memberOf:1.2.840.113556.1.4.1941: 扩展,但不确定如何使其适应我的代码。我的工作代码在下面(它只是不做嵌套组)。有经验的人可以帮忙吗?
输入CONFIG.PHP
$adbase = "some.domain.com";
$adtree = "OU=All Departments,DC=some,DC=domain,DC=com";
$group_admins = "Test App Admins";
$group_staff = "Test App Staff";
在RUN.PHP
function extract_unit($string, $start, $end) {
$pos = stripos($string, $start);
$str = substr($string, $pos);
$str_two = substr($str, strlen($start));
$second_pos = stripos($str_two, $end);
$str_three = substr($str_two, 0, $second_pos);
$unit = trim($str_three); // remove whitespaces
return $unit;
}
extract($_POST);
if($action == "logon") {
$ldap = ldap_connect($adbase);
$userID = "$user@$adbase";
$bind = @ldap_bind($ldap, $userID, $pass);
if($bind == true) {
// assign session variables
$_SESSION['username'] = $user;
// get group memberships
$results = ldap_search($ldap, $adtree, "(samaccountname=$user)",array("memberof", "mail"));
$entries = ldap_get_entries($ldap, $results);
// get group count (first entry) and group listings
$beat = 0; $str = ""; foreach($entries[0]['memberof'] as $temp) {
if($beat == 0) {
$count = $temp;
}
else {
$temp = extract_unit($temp, "CN=", ",OU=");
$str .= "$temp, ";
$groups[] = $temp;
}
$beat++;
}
// return the mail address, whosebug.com/questions/16224720/searching-for-email-address-ldap-active-directory
$mail = $entries[0]["mail"][0];
// assign session variables
$_SESSION['mail'] = $mail;
// groups defined in config.php
$client = "You are logged in as a client.";
if(in_array($group_admins, $groups)) {
$_SESSION['admin'] = true;
$client = "You are logged in as an administrator.";
}
else {
$_SESSION['admin'] = false;
}
// groups defined in config.php
if(in_array($group_staff, $groups)) {
$_SESSION['staff'] = true;
$client = "You are logged in as staff.";
}
else {
$_SESSION['staff'] = false;
}
// if it returns true user was found
print "<h2>Signed in as $user</h2>\n";
print "$client<br>\n";
print "<img src=\"./images/next.png\"> <a href=\"./?d=welcome\">Continue ...</a>\n";
print "<!-- count is $count -->";
print "<!-- groups are $str -->";
print "<!-- mail is $mail -->";
}
else {
print "<h2>Login attempt failed</h2>\n";
print "<img src=\"./images/logon.png\"> <a href=\"./?d=user/logon\">You may try again ...</a>\n";
}
}
您需要使用类似于以下的可扩展匹配过滤器语法构建查询:
(memberOf:1.2.840.113556.1.4.1941:=CN=GroupOne,OU=安全组,OU=组,DC=YOURDOMAIN,DC=NET)
哪个RESOLVES ALL MEMBERS (INCLUDING NESTED) SECURITY GROUPS (REQUIRES AT LEAST WINDOWS 2003 SP2)
我终于开始工作了,但我不得不走另一条路。
这是我最终 PHP LDAP 身份验证工作的代码,带有嵌套组。 这假定正在检查用户名以查看它是否存在于组或嵌套组中。如果你取出 (samaccountname=$user) 那么它将 return 该组中所有用户的列表,但它会花费相当长的时间(不到一秒到 30+ 秒)。
/*
$adBase like "some.domain.com"
$ldBase like "OU=Users,DC=some,DC=domain,DC=com"
$admins like "CN=Test Admins,OU=Groups"
$staff like "CN=Test Staff,OU=Groups"
$ldaplink like "ldap://ldap.domain.com/o=domain.com??sub?"
*/
$ldap = ldap_connect($adBase);
$bind = @ldap_bind($ldap, "$user@$adBase", $pass);
$admins = $ldAdmin.",".$ldBase;
$staffs = $ldStaff.",".$ldBase;
$filtrA = "(&(objectClass=user)(samaccountname=$user)(memberof:1.2.840.113556.1.4.1941:=$admins))";
$filtrS = "(&(objectClass=user)(samaccountname=$user)(memberof:1.2.840.113556.1.4.1941:=$staffs))";
if($bind) {
// default message if not found in either group
$client = "You are logged in as a client.";
// get basic info first; whosebug.com/questions/1622472...
$result = ldap_search($ldap, $ldBase, "(samaccountname=$user)", array("mail"));
$entries = ldap_get_entries($ldap, $result);
$mail = $entries[0]["mail"][0];
$_SESSION['username'] = $user;
$_SESSION['mail'] = $mail;
#region check admin/nested group
$link1A = ldap_search($ldap, $ldBase, $filtrA, array("name"));
$link2A = ldap_get_entries($ldap, $link1A);
@$nameA = $link2A[0]["name"][0]; // throws error if not defined but that's what we're testing thus the @
if($nameA == true) {
// user was found in administrators or in nested group
$_SESSION['admin'] = true;
$client = "You are logged in as an administrator.";
}
else {
$_SESSION['admin'] = false;
}
#endregion
#region check staff/nested group
$link1S = ldap_search($ldap, $ldBase, $filtrS, array("name"));
$link2S = ldap_get_entries($ldap, $link1S);
@$nameS = $link2S[0]["name"][0]; // throws error if not defined but that's what we're testing thus the @
if($nameS == true) {
// user was found in staff or in nested group
$_SESSION['staff'] = true;
$client = "You are logged in as staff.";
}
else {
$_SESSION['staff'] = false;
}
#endregion
// if it returns true user was found
print "<h2>Signed in as $user</h2>\n";
print "$client<br>\n";
print "<img src=\"./images/next.png\"> <a href=\"./?d=tem/welcome\">Continue ...</a>\n";
print "<!-- mail is $mail -->";
}
else {
print "<h2>Login attempt failed</h2>\n";
print "<img src=\"./images/logon.png\"> <a href=\"./?d=user/logon\">You may try again ...</a>\n";
}