简体   繁体   中英

Converting Classic ASP LDAP Binding Script to PHP

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM