将经典ASP LDAP绑定脚本转换为PHP

时间:2018-04-23 21:30:57

标签: php asp-classic ldap

我正在将我们组织的经典ASP LDAP身份验证脚本转换为PHP,虽然我知道在PHP中可能没有直接的等价物,但这种特殊方法让我感到难过。

基本上,在我的组织现有的经典ASP代码中,有两个函数:一个用于返回userPrincipalName,另一个用于实际绑定userPrincipalName和密码,因此进行身份验证。

我试图在PHP中复制这个概念,但它没有成功,因为第二个绑定(身份验证)不成功,而第一个绑定(获取userPrincipalName)成功。
在我的测试中,在这里,在第二个绑定代码中,我将用户名和密码硬编码到代码中并得到这些错误:

ldap_error: Invalid credentialsldap_error_no: 49

ldap_get_option: 80090308: LdapErr: DSID-0C090400, comment: AcceptSecurityContext error, data 52e, v1db1

以下是这两个函数的脚本(在Classic ASP中),然后是Classic ASP代码,然后是新的PHP尝试。 感谢任何线索!

经典ASP(这些都有效):

功能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

功能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

这两个函数如何在Classic ASP代码中起作用:

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尝试: 以下是3个PHP脚本,它们构成了我将Classic ASP LDAP脚本的功能引入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 

1 个答案:

答案 0 :(得分:0)

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;

    }