I'm in the process of converting our organization's Classic ASP LDAP Authentication script to PHP, and, while I know there may not be a straight equivalent in PHP, this particular approach has me stumped.
Basically, in my organization's existing Classic ASP code, there are 2 functions: one for returning the userPrincipalName, and then another for actually binding the userPrincipalName and password and thusly, authenticating.
I've got an attempt at replicating this concept in PHP, but it hasn't been successful, in that the 2nd bind (the authentication) is not successful, while the 1st bind (that gets the userPrincipalName) is successful.
In my test, here, in the 2nd binding code, I hardcode the username and password into the code and get these errors:
ldap_error: Invalid credentialsldap_error_no: 49
ldap_get_option: 80090308: LdapErr: DSID-0C090400, comment: AcceptSecurityContext error, data 52e, v1db1
Here are the scripts for those two functions (in Classic ASP), followed by the Classic ASP code, and then the new PHP attempt. Thanks for any leads!
Classic ASP (these are all working):
Function BindReturnUPN:
Function BindReturnUPN(username,domain)
On Error Resume Next
strUser = "schoolName\schoolName-web-acnt"
strPass = "password"
set cnnLDAP = Server.CreateObject("ADODB.Connection")
set rstLDAP = Server.CreateObject("ADODB.RecordSet")
cnnLDAP.Provider = "ADSDSOObject"
cnnLDAP.Properties("User ID") = strUser
cnnLDAP.Properties("Password") = strPass
cnnLDAP.Properties("Encrypt Password") = True
cnnLDAP.Open
strSQL="<GC://tsu.net.ps.edu:3268>;(&(objectClass=user)(objectCategory=person)(userPrincipalName=" & username & "@" & domain & "*));userPrincipalName,cn,sAMAccountName,displayName,distinguishedName;subtree"
rstLDAP.open strSQL,cnnLDAP,0,1,0
If Err.Number = -2147217911 Then Response.Write "Bad Password "
If Err.Number <> 0 Then
Response.Write Err.Number & " " & Err.Description
Response.End
End If
BindReturnUPN = rstLDAP("userPrincipalName")
End Function
Function BindAuthUPN:
Function BindAuthUPN(upn,password)
On Error Resume Next
set cnnLDAP = Server.CreateObject("ADODB.Connection")
set rstLDAP = Server.CreateObject("ADODB.RecordSet")
cnnLDAP.Provider = "ADSDSOObject"
cnnLDAP.Properties("User ID") = upn
cnnLDAP.Properties("Password") = password
cnnLDAP.Properties("Encrypt Password") = True
cnnLDAP.Open
strSQL="<GC://tsu.net.ps.edu:3268>;(&(objectClass=user)(objectCategory=person)(userPrincipalName=" & username & "@" & domain & "*));userPrincipalName,cn,sAMAccountName,displayName,distinguishedName;subtree"
rstLDAP.open strSQL,cnnLDAP,0,1,0
If Err.Number = -2147217911 Then Response.Write "<div align=""center"" style=""border:1px solid #ccc; padding:10px 10px 10px 10px; margin:10px 10px 10px 10px; background-color: #eee;""> " & _
"Incorrect Password for user " & fmUsername & "<br><a href=""loginform.asp"">Try Again</a></div>"
If Err.Number <> 0 Then
Response.Write("<script type=""text/javascript"">alert('Incorrect Password for user " & fmUsername & "')</script>")
Response.Write Err.Number & " " & Err.Description
Response.End
End If
BindAuthUPN = Trim(Err.Number & " " & Err.Description)
End Function
End If
How the 2 functions work in the Classic ASP code:
If fmUsername <> "" Then
ReturnedUPN = BindReturnUPN(fmUsername,fmDomain)
If ReturnedUPN = "" Then ReturnedUPN = "(nothing returned)"
If ReturnedUPN = "(nothing returned)" Then
AuthStatus = "User " & fmUsername & " cannot be found."
Response.Write(AuthStatus)
Else
AuthStatus = BindAuthUPN(ReturnedUPN,fmPassword)
End If
If AuthStatus = "0" Then
Response.Cookies("UserName") = fmUsername
Response.Cookies("UserName").Expires = DateAdd("d", 3, Now())
%>
<div>
<strong>Login Successful!</strong><br><br>
</div>
<%
Else
Response.Write "<div>"& AuthStatus & "<br><a href=""loginform.asp"">Try Again</a></div>"
End If
End If
End If
PHP attempts: Here are the 3 PHP scripts that form my attempt to bring the functionality from the Classic ASP LDAP script to PHP.
authenticate.php
// active directory server
$ldap_host = "server.college.school.edu";
// Set the debug flag
$debug = true;
// Set debugging
if ($debug) {
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
}
// active directory DN (base location of ldap search)
$ldap_dn = "OU=Departments,DC=college,DC=school,DC=edu";
//below - admin account to gain access
$adminDN = "schoolName\schoolName-web-acnt";
$adminPswd = "password";
// active directory user group name
//$ldap_student_group = "ALL-STUDENTS";
// domain, for purposes of constructing $user
//$ldap_usr_dom = 'schoolName\web-account';
// connect to active directory
$ldap_conn = ldap_connect($ldap_host) or die ("Couldn't connect");
// configure ldap params
ldap_set_option($ldap,LDAP_OPT_PROTOCOL_VERSION,3);
ldap_set_option($ldap,LDAP_OPT_REFERRALS,0);
if (! $ldap_conn) {
echo ("<p style='color: red;'>Couldn't connect to LDAP service</p>");
}
else {
echo ("<p style='color: green;'>Connection to LDAP service successful!</p>");
}
//The first step is to bind the administrator so that we can search user info
$ldapBindAdmin = ldap_bind($ldap_conn, $adminDN, $adminPswd);
if ($ldapBindAdmin){
echo ("<p style='color: green;'>Admin binding and authentication successful!!!</p>");
$filter = '(sAMAccountName=jsmith)';
$attributes = array("name", "telephonenumber", "mail", "samaccountname", "userprincipalname");
$result = ldap_search($ldap_conn, $ldap_dn, $filter, $attributes);
$entries = ldap_get_entries($ldap_conn, $result);
$userDN = $entries[0]["name"][0];
$userPrincipalName = $entries[0]["userprincipalname"][0];
echo ('<p style="color:green;">I have the user DN: '.$userDN.'</p>');
echo ('<p style="color:green;">I have the userPrincipalName: '.$userPrincipalName.'</p>');
$domain='schoolName';
$password='password';
//Okay, we're in! But now we need bind the user now that we have the user's DN
$ldapBindUser = ldap_bind($ldap_conn, $userPrincipalName, $password);
if (!$ldapBindUser) {
echo "Unable to bind to server $ldap_host\n";
echo "OpenLdap error message: " . ldap_error($ldap_conn) . "\n";
//exit;
}
if($ldapBindUser){
echo ("<p style='color: green;'>User binding and authentication successful!!!</p>");
ldap_unbind($ldap_conn); // Clean up after ourselves.
} else {
echo ("<p style='color: red;'>There was a problem binding the user to LDAP :(</p>");
echo "ldap_error: " . ldap_error($ldap_conn);
echo "ldap_error_no: " . ldap_errno($ldap_conn);
echo "<br>";
ldap_get_option($ldap_conn, LDAP_OPT_DIAGNOSTIC_MESSAGE, $err);
echo "ldap_get_option: $err";
} //end - $ldapBindUser check
} else {
echo ("<p style='color: red;'>There was a problem binding the admin to LDAP :(</p>");
} //end - $ldapBindAdmin check
ldapServer='192.168.1.75';
ldapPort='389';
basedn='DC=nps,DC=com';
attribName='homephone';//or any attribute that you want
/***
* Authenticate against LDAP Server
* see config on top of this file (all vars are in private scope)
* @param string (login like user@domain.com)
* @param string (password)
* @return mixed (attribute value| boolean)
*/
private function authenticate($login=null,$pass=null){
if(is_null($login) || empty($login) || is_null($pass) || empty($pass))
return false;
$con=ldap_connect($this->ldapServer,$this->ldapPort);
if($con){
ldap_set_option($con,LDAP_OPT_PROTOCOL_VERSION,3);
ldap_set_option($con, LDAP_OPT_REFERRALS, 0);
ldap_set_option($con,LDAP_OPT_TIMELIMIT,10);
try{
$auth=ldap_bind($con,$login,$pass);
if($auth){
$filter ="(&(objectCategory=person)(userprincipalname={$login}))";
$fields = array($this->attribName);
$res = ldap_search($con,$this->basedn, $filter,$fields);
if(isset($res) && !empty($res)){
$entries = ldap_get_entries($con, $res);
@ldap_close($con);
if(isset($entries[0][$this->attribName][0]) && !empty($entries[0][$this->attribName][0]))
return $entries[0][$this->attribName][0];
else
return false;
}else
return false;
}else
return false;
}catch (\Exception $e){
@ldap_close($con);
return false;
}
}else
return false;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.