我很惊讶那里的例子很少。我基本上需要针对Active Directory进行用户/通过身份验证。我能够初始化到活动目录的连接,但它总是给我一个“无效的凭据”错误。我想知道我是不是错了。这是我第一次使用LDAP。就此而言,我对另一个(也许有很多文件记录)解决方案持开放态度。
#include <iostream>
#include <stdio.h>
#define LDAP_SERVER "ldap://hq.mydomain.local/"
#include <ldap.h>
int main( int argc, char** argv )
{
LDAP *ld;
int version( LDAP_VERSION3 );
int rc;
char bind_dn[100];
berval creds;
berval* serverCreds;
if( ldap_initialize( &ld, LDAP_SERVER ) ) {
std::cerr << "Error initializing ldap..." << std::endl;
return 1;
}
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
creds.bv_val = "password";
creds.bv_len = strlen("password");
rc = ldap_sasl_bind_s( ld, "sAMAccountName=MYDOMAIN\\UserName,dc=mydomain,dc=local", "GSSAPI", &creds, NULL, NULL, &serverCreds );
if ( rc != LDAP_SUCCESS ) {
std::cerr << "ERROR: " << ldap_err2string( rc ) << std::endl;
return 1;
} else {
std::cout << "Success." << std::endl;
}
return 0;
}
编辑:
我想确保服务器端的一切正常,所以使用ldapsearch进行了一些测试。它最初没有用,但我终于得到了它(无论如何都是ldapsearch)。
ldapsearch -D first.last@mydomain.local -H "ldap://hq.mydomain.local:389" -b "ou=Development,ou=Domain Users,dc=mydomain,dc=local" -W "sAMAccountName=first.last"
也许不是最好的方式。对于初学者,键是-D参数,并在结尾传递sAMAccountName。我不会有通用名称 - 只有Windows登录名和密码。如果密码通过,上面的命令将向用户显示他的信息。
警告(我认为)是ldap_sasl_bind_s()没有相当于设置-D(binddn)标志。看看this question/answer它看起来像ldap_interactive_bind_s(),但它更复杂一些,因为我必须传回一个回电。
上面的示例中我设置了密码,但没有任何类型的binddn / username,是谁假设我正在尝试进行身份验证?
答案 0 :(得分:2)
sAMAccountName赋= MYDOMAIN \用户名,DC = MYDOMAIN,DC =本地
此用户名格式不正确。您无需在用户名中指定sAMAccountName
,也无需指定dc
,除非您使用Distinguished Name
。用户名很少。
CN = Jeff Smith,OU = Sales,DC = Fabrikam,DC = Com
jsmith的
&#34;的Fabrikam \ jeffsmith&#34;
jeffsmith@Fabrikam.com
话虽如此,我不确定用户名是否是您遇到的唯一问题。我没有在本地运行你的代码。
虽然这个答案可能无法直接回答你的问题,但由于我没有在Linux机器上测试过这段代码,它可以给你一个想法或让你朝着正确的方向前进。 如果此方法仅限于Windows,我不会感到惊讶。
根据MSDN,您可以使用少量methods
来验证用户身份。
ADsOpenObject函数使用显式用户名和密码凭据绑定到ADSI对象。
此方法接受以下参数:
HRESULT ADsOpenObject(
_In_ LPCWSTR lpszPathName,
_In_ LPCWSTR lpszUserName,
_In_ LPCWSTR lpszPassword,
_In_ DWORD dwReserved,
_In_ REFIID riid,
_Out_ VOID **ppObject
);
使用此方法,您可以通过指定username
和password
绑定到Active Directory中的对象。
如果绑定成功,则返回代码为S_OK
,否则您将收到不同的错误消息。
我不会每天在C++
编写程序。我通常在Active Directory
世界中使用Active Directory Lightweight Services
和C#
。但是我编写的示例代码向您展示了如何使用指定的凭据调用ADsOpenObject
方法绑定到ADSI对象。在您的情况下,只需authenticate
。
#include <iostream>
#include "activeds.h"
using namespace std;
int main(int argc, char* argv[])
{
HRESULT hr;
IADsContainer *pCont;
IDispatch *pDisp = NULL;
IADs *pUser;
CoInitialize(NULL);
hr = ADsOpenObject( L"LDAP://yourserver",
L"username",
L"password",
ADS_FAST_BIND, //authentication option
IID_IADs,
(void**) &pUser);
if (SUCCEEDED(hr))
{
cout << "Successfully authenticated";
}
else
cout << "Incorrect username or password";
return hr;
}
根据您的设置,您可能需要调整ADS_AUTHENTICATION_ENUM
。我建议您安装 SSL证书并使用ADS_USE_SSL
绑定。在AD中处理没有SSL的密码可能是噩梦。