Аутентификация Java LDAP с именем пользователя

Ладно, это сводит меня с ума. Я пытаюсь создать аутентификацию LDAP с помощью Java, и все в порядке, если я использую свое имя и фамилию в SECURITY_PRINCIPAL. Это мой код:

 try {
    Hashtable<String, String> ldapEnv = new Hashtable<String, String>();
    ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    ldapEnv.put(Context.PROVIDER_URL,  "LDAP://myldap.mydomain.com:389");
    ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
    ldapEnv.put(Context.SECURITY_PRINCIPAL, "CN=FirstName LastName" + ",ou=Users");    
    ldapEnv.put(Context.SECURITY_CREDENTIALS, "password");

    DirContext ldapContext = new InitialLdapContext(ldapEnv, null);
    }
    catch (Exception e) {
      System.out.println(" bind error: " + e);
      e.printStackTrace();
   }

Проблема в том, что он не работает с моим именем пользователя. Если я попытаюсь:

ldapEnv.put(Context.SECURITY_PRINCIPAL, "CN=myusername" + ",ou=Users");

Or

ldapEnv.put(Context.SECURITY_PRINCIPAL, "uid=myusername" + ",ou=Users");

Я всегда получаю [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1]

По какой-то причине это работает только с моим именем и фамилией. Я проверил AD, и мое sAMAccountName — это правильное имя пользователя. Не уверен, почему это происходит. У кого-нибудь еще были такие проблемы? Могу ли я передать что-то еще в Context.SECURITY_PRINCIPAL? Я пробовал ldapEnv.put(Context.SECURITY_PRINCIPAL, "sAMAccountName=myusername" + ",ou=Users");, но тоже не получается... Кто-нибудь может помочь?


person Koshera    schedule 11.02.2016    source источник


Ответы (2)


EJP, спасибо за ваш вклад. Вы действительно правы, но я искал что-то простое - просто передайте имя пользователя и пароль в AD и посмотрите, аутентифицируется он или нет. Я должен был быть более конкретным в своем первом сообщении. Ваше предложение будет работать, но я думаю, что это намного проще:

            Hashtable props = new Hashtable();
            String principalName = "[email protected]";
            props.put(Context.SECURITY_PRINCIPAL, principalName);
            props.put(Context.SECURITY_CREDENTIALS, "mypassword");
            DirContext context;

                //try to authenticate
            try {

                   context = com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance("LDAP://myldap.mydomain.com:389" + '/', props);
                   context.close();                    
            }

Таким образом, я не забочусь о DN. Просто передать имя пользователя@домен и вуаля - работает как шарм :) Еще раз спасибо!

person Koshera    schedule 11.02.2016
comment
Хотя ваш метод будет работать, если все звезды совпадают, а имя пользователя@exmaple.com согласовано, но метод @EJP является наилучшей практикой. Пример можно найти по адресу: bitbucket.org/jwilleke/examples/src/ - person jwilleke; 12.02.2016
comment
Мой метод работает безупречно без выравнивания по звездам ;) Пользователи просто используют свое имя пользователя так, как оно используется в AD - простое имя пользователя. Я прикрепляю @domaindetails в конце и передаю его для аутентификации. Если аутентификация не удалась - выбрасывает AuthenticationException. Красиво, чисто, просто и быстро! Вам не нужно использовать учетную запись администратора LDAP, аутентифицироваться с ее помощью, искать другую учетную запись, получать DN, проверять пароль, а затем... - person Koshera; 13.02.2016
comment
В моем случае это сработало с [email protected]. - person Alok; 05.09.2018

Нет записи, DN которой содержит UID или CN=username. Вы должны предоставить существующую запись, а не просто произвольную строку атрибутов. Обычный метод заключается в том, чтобы привязаться как пользователь-администратор, найти пользователя, у которого есть этот UID или что-то еще, что он предоставил вашей системе входа, получить DN этого пользователя, а затем попытаться выполнить привязку в качестве этого DN с предоставленным пользователем oassword.

person user207421    schedule 11.02.2016