【问题标题】:Converting Classic ASP LDAP Binding Script to PHP将经典 ASP LDAP 绑定脚本转换为 PHP
【发布时间】:2018-04-23 21:30:56
【问题描述】:

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

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

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

ldap_error: Invalid credentialsldap_error_no: 49

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

以下是这两个函数的脚本(在经典 ASP 中),接着是经典 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

这 2 个函数如何在经典 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 脚本,它们构成了我将经典 ASP LDAP 脚本的功能引入 PHP 的尝试。

认证.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 

【问题讨论】:

  • 你在哪里被屏蔽了?你可以直接通过用户名和密码绑定,我会给你一个我使用的例子你也可以查看这个 repo github.com/med-ezzairi/LDAP_PHP
  • 两步流程只适用于无法直接绑定的系统/语言吗?

标签: php asp-classic ldap


【解决方案1】:
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;

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多