简体   繁体   English

使用LDAP和Windows Active Directory的用户身份验证(Windows Server 2016)

[英]User Authentication using LDAP with Windows Active Directory (Windows Server 2016)

Platform : Windows 10 x64 Development Environment : MSVC 2017 平台:Windows 10 x64开发环境:MSVC 2017

Active Directory Platform : Windows Server 2016 (Evaluation) Active Directory平台:Windows Server 2016(评估)

I am trying to authenticate windows users located on remote server maintained using Windows Active Directory. 我正在尝试对使用Windows Active Directory维护的远程服务器上的Windows用户进行身份验证。 My service running on local PC is giving Invalid Credentials error message (even after passing proper authenticated user name, password and domain). 我在本地PC上运行的服务给出了“ 无效凭据”错误消息(即使在传递正确的经过身份验证的用户名,密码和域之后)。

#include "pch.h"
#include <iostream>
#include <Windows.h>
#include <Winldap.h>
#include <plog/Log.h>
#include <string>

#ifdef UNICODE
typedef std::wstring        string_type;
#define CONSOLE_OUT         std::wcout
#define CONSOLE_IN          std::wcin
#define CONSOLE_ERR         std::wcerr
#else
typedef std::string         string_type;
#define CONSOLE_OUT         std::cout
#define CONSOLE_IN          std::cin
#define CONSOLE_ERR         std::cerr
#endif

int main()
{
    SEC_WINNT_AUTH_IDENTITY sec;
    string_type hostName = TEXT("192.168.1.49");
    string_type domain = TEXT("WIN-49MT1TDDGOC.darksorrow.com");
    string_type userName = TEXT("darksorrow\\ds");
    string_type password = TEXT("darksorrow@1234567890");
    PLDAP ld = nullptr;
    int ldapReturnCode;
    CONSOLE_OUT << TEXT("Hello World!\n");
    plog::init(plog::error, "error.dat", 1048576, 3); //1 M.B.
    ld = ldap_init(const_cast<PWSTR>(hostName.c_str()), LDAP_PORT);

    if (ld == nullptr)
    {
        LOG_ERROR << ldap_err2string(LdapGetLastError());
        CONSOLE_OUT << ldap_err2string(LdapGetLastError());
    }
    const int version = LDAP_VERSION3;
    ldapReturnCode = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, std::addressof(version));
    if (ldapReturnCode not_eq LDAP_SUCCESS)
    {
        LOG_ERROR << ldap_err2string(ldapReturnCode);
        CONSOLE_OUT << ldap_err2string(ldapReturnCode);
    }
    ldapReturnCode = ldap_connect(ld, NULL);
    if (ldapReturnCode not_eq LDAP_SUCCESS)
    {
        LOG_ERROR << ldap_err2string(ldapReturnCode);
        CONSOLE_OUT << ldap_err2string(ldapReturnCode);
    }
    PWSTR   dn = nullptr;

    sec.Domain          = (unsigned short *) domain.data();
    sec.DomainLength    = domain.length();
    sec.User            = (unsigned short *) userName.data();
    sec.UserLength      = userName.length();
    sec.Password        = (unsigned short *) password.data();
    sec.PasswordLength  = password.length();
    sec.Flags           = SEC_WINNT_AUTH_IDENTITY_UNICODE;

    CONSOLE_OUT << domain << std::endl;
    CONSOLE_OUT << userName << std::endl;
    CONSOLE_OUT << password << std::endl;

    ldapReturnCode = ldap_bind_s(ld, dn, (PWCHAR)std::addressof(sec), LDAP_AUTH_NEGOTIATE);
    if (ldapReturnCode not_eq LDAP_SUCCESS)
    {
        LOG_ERROR << ldap_err2string(ldapReturnCode);
        CONSOLE_OUT << ldap_err2string(ldapReturnCode);
    }
    else
        CONSOLE_OUT << "Authentication Success\n";
    ldap_unbind(ld);
    return EXIT_SUCCESS;
}

Where am I going wrong? 我要去哪里错了?

I decided to give this a try myself. 我决定自己尝试一下。 Turns out the solution is simple. 事实证明,解决方案很简单。 Your username should not contain the domain name. 您的用户名不应包含域名。 So change this: 所以改变这个:

string_type userName = TEXT("darksorrow\\ds");

to this: 对此:

string_type userName = TEXT("ds");

You are already specifying the domain as a separate parameter, so it's not needed as part of the username. 您已经将域指定为单独的参数,因此不需要作为用户名的一部分。

You should be able to still use LDAP_AUTH_NEGOTIATE . 您应该仍然可以使用LDAP_AUTH_NEGOTIATE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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