Не удалось получить пользователей с сервера LDAP AD - PullRequest
0 голосов
/ 14 января 2019

Я создал сервер LDAP AD на сервере Windows 2008, выполнив действия, указанные в следующей ссылке:

https://blogs.msdn.microsoft.com/robert_mcmurray/2011/09/16/ftp-and-ldap-part-2-how-to-set-up-an-active-directory-lightweight-directory-services-ad-lds-server/#01b

Следующая программа должна искать пользователей в LDAP AD. Он успешно соединяется с сервером LDAP, но поиск пользователя не выполнен. Я не уверен почему.

public class LDAPTest {
String ldapHost = "ldap://hostname:389";
String searchBase = "CN=LDAPServer,DC=SITDomain,DC=local";

public static void main(String[] args) {
    LDAPTest ldapConnect = new LDAPTest();
    ldapConnect.authenticate("john", "****");
}

public Map authenticate(String user, String pass) {
    String returnedAtts[] = { "dintinguishedName" };
    String searchFilter = "(& (userPrincipalName="+user+")(objectClass=user))";

    // Create the search controls
    SearchControls searchCtls = new SearchControls();
    searchCtls.setReturningAttributes(returnedAtts);

    // Specify the search scope
    searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);

    Hashtable<Object, Object> env = new Hashtable<Object, Object>();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, this.ldapHost);
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL,"CN=ryan,CN=grp,CN=LDAPServer,DC=SITDomain,DC=local");
    env.put(Context.SECURITY_CREDENTIALS, pass);

    LdapContext ctxGC = null;
    boolean ldapUser = false;

    try {
        ctxGC = new InitialLdapContext(env, null);
        // Search objects in GC using filters
        NamingEnumeration<SearchResult> answer = ctxGC.search(this.searchBase, searchFilter, searchCtls);
        while (answer.hasMoreElements()) {
            SearchResult sr = answer.next();
            System.out.println(">>>" + sr.getName());
            Attributes attrs = sr.getAttributes();
            Map amap = null;
            if (attrs != null) {
                System.out.println(attrs.size());
                System.out.println(">>>>>>" + attrs.get("dintinguishedName"));
                amap = new HashMap();
                NamingEnumeration<Attribute> ne = (NamingEnumeration<Attribute>) attrs.getAll();
                while (ne.hasMore()) {
                    Attribute attr = ne.next();
                    amap.put(attr.getID(), attr.get());
                    System.out.println(attr.getID()+">>>>>>" + attr.get());
                    ldapUser = true;
                }
                ne.close();
            }
        }

    } catch (NamingException ex) {
        ex.printStackTrace();
        System.out.println(ex.getMessage());
    }

    return null;
}

}

Образ dir-сервера LDAP

1 Ответ

0 голосов
/ 16 января 2019

Не уверен, что это ошибка копирования / вставки или опечатка в коде, но возвращаемый атрибут пользователя пишется неправильно. Имя атрибута dintinguishedName должно отличаться от Name. Я также ожидал бы увидеть начальное связывание с известным хорошим пользователем (например, учетную запись, специально созданную для приложения), поиск пользователя, поиск отличительного имени и вторую попытку связать с возвращенным отличительным именем и предоставленным пользователем паролем. , Вместо этого я вижу жестко идентифицированный идентификатор (ryan), используя предоставленный пользователем пароль. Что может сработать, если две учетные записи имеют одинаковый пароль. Ниже этой статьи я включил код, который я использую для аутентификации на своих серверах LDAP, включая Active Directory.

Я хотел использовать универсальный код, и большинство других серверов LDAP требуют, чтобы вы указывали на имя привязанного в процессе привязки. Но для Active Directory, в частности, вы можете выполнить привязку, не зная отличительного имени пользователя - привязка LDAP к AD может быть выполнена с помощью sAMAccountName (домен \ пользователь) и userPrincipalName (user@domain.TLD). Если у вас есть одно дерево в одном лесу (то есть вы знаете значение, добавляемое к идентификатору пользователя для формирования sAMAccountName или userPrincipalName), вы можете выполнить операцию связывания как пользователь. Если вам необходима дополнительная информация о человеке, выходящем за рамки проверки подлинности, при коде возврата 0 (успешная проверка подлинности) найдите пользователя и получите информацию.

 // Editable variables -- ensure you change these to your application's details
String strSysUID = "uid=YOURSYSTEMIDGOESHERE,ou=OrgUnitName,dc=Org,dc=Name";
String strSysPassword = "YourSystemPasswordGoesHere";
String strAuthorizationGroup = "LJL_Test";
String strTrustStorePassword = "YourTrustStorePassword"

String trustStoreFile = ".\\ADTrust";

String sLDAPServer = "ldaps://ldap.domain.gTLD:636";
String strUserBaseDN = "ou=UserOU,dc=Org,dc=Name";
String strGroupBaseDN = "ou=GroupOU,dc=Org,dc=Name";
String strUserIDSchemaAttribute = "sAMAccountName=";            // attribute that holds user logon name
String strGroupMembershipSchemaAttribute = "member";            // attribute that holds member list in group object
// End of editable variables

System.setProperty("javax.net.ssl.trustStore", trustStoreFile);
System.setProperty("javax.net.ssl.trustStorePassword", strTrustStorePassword);

// Obtain UID and PWD from user
String sUserUID = "";
String sUserPwd = "";

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

System.out.print("Please enter your username: ");

try{
    sUserUID = in.readLine();
}catch(Exception er) { er.printStackTrace(); }

System.out.print("Please enter your password: ");
try{
    sUserPwd = in.readLine();
}catch(Exception er) { er.printStackTrace(); }

// Initial context for system bind
Hashtable env = new Hashtable(11);
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, sLDAPServer);
env.put(Context.SECURITY_PROTOCOL, "ssl");

// Authenticate as system ID and password
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, strSysUID);
env.put(Context.SECURITY_CREDENTIALS, strSysPassword);

try {
    DirContext ctx = new InitialDirContext(env);

    // Using the system credentials, search for a user matching the logon ID provided by the user
    String sFilter = strUserIDSchemaAttribute + sUserUID;
    NamingEnumeration UserDNAnswer = ctx.search(strUserBaseDN, sFilter, null);

    String sReturnedFQDN = "";
    // If only one record should be returns, validate that exactly one record is located and throw an error otherwise
    while (UserDNAnswer.hasMore()) {
        SearchResult sr = (SearchResult) UserDNAnswer.next();
        // Store the DN of the user re have found
        sReturnedFQDN = sr.getNameInNamespace();
    }

    // Check group membership, can be done after the password is validated if you wish
    // Example LDAP filter is "(&(cn=NameOfGroupToCheck)(uniqueMember=FQDNOfUserBeingTested))"
    String sGroupFilter = "(&(cn=" + strAuthorizationGroup + ")(" + strGroupMembershipSchemaAttribute + "=" + sReturnedFQDN + "))";
    NamingEnumeration GroupMembershipAnswer = ctx.search(strGroupBaseDN, sGroupFilter, null);

    String sReturnedGroupDN = "";
    while (GroupMembershipAnswer.hasMore()) {
        SearchResult srGroup = (SearchResult) GroupMembershipAnswer.next();
        sReturnedGroupDN = srGroup.getNameInNamespace();
    }

    ctx.close();
    // If an entry was returned, then the user is a member of the group. We should validate the user's password
    if(sReturnedGroupDN.equals("cn=" + strAuthorizationGroup+ "," + strGroupBaseDN)){
        System.out.println(sReturnedFQDN + " is a member of " + sReturnedGroupDN + " and now we will validate the password.");

        // Now establish a new LDAP connection to validate the credentials supplied
        Hashtable envUser = new Hashtable(11);
        envUser.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        envUser.put(Context.PROVIDER_URL, sLDAPServer);

        // Authenticate using the searched FQDN for the user and the password provided by the user
        envUser.put(Context.SECURITY_AUTHENTICATION, "simple");
        envUser.put(Context.SECURITY_PRINCIPAL, sReturnedFQDN);
        envUser.put(Context.SECURITY_CREDENTIALS, sUserPwd);

        // Doing this so a login failure throws a code
        try{
            DirContext ctxUser = new InitialDirContext(envUser);
            System.out.println("Successfully authenticated as " + sUserUID);
            ctxUser .close;
        }
        // User credentials failure
        catch (NamingException e) {
            e.printStackTrace();
        }
    }
    // If no group matched the filter, the user is not a group member and an authorisation failure can be returned
    else{
        System.out.println(sReturnedFQDN + " is NOT a member of " + sReturnedGroupDN + " and there is no need to verify the password.");
    }
}
// System credentials failure
catch (NamingException e) {
    e.printStackTrace();
}

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...