2016-11-11 7 views
0

UPDATE 11/14: Я проверил через нашу команду ops, что имя пользователя/пароль действительны при входе в систему через интерфейс Active Directory. Таким образом, это только программно, что не удается.LDAP AD не может аутентифицировать пользователя, которого я только что создал

Я работаю с простым сервером Active Directory и проверяю возможность создания нового пользователя, а затем аутентифицирую этого пользователя, используя только что установленные учетные данные.

Я могу успешно аутентифицировать существующего пользователя (созданного через интерфейс администратора на сервере); Я могу создать нового пользователя и установить пароль (см. Ниже фрагмент кода); Я могу найти, что пользователь успешно

Однако при попытке аутентификации с использованием учетных данных, предоставленных мной, я получаю

javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db0] 

Ниже приводится код для аутентификации пользователя

public UserEntity authenticate (@NotNull final String username, 
            @NotNull final String password) 
    throws NamingException 
{ 
    try 
    { 
     Hashtable<String, Object> env = new Hashtable<>(); 

     env.put(Context.SECURITY_AUTHENTICATION,"simple"); 
     env.put(Context.SECURITY_PRINCIPAL,  username); 
     env.put(Context.SECURITY_CREDENTIALS, password); 
     env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); 
     env.put(Context.PROVIDER_URL,   "ldaps://<host>:636"); 
     env.put(Context.SECURITY_PROTOCOL,  "ssl") ; 

     LdapContext context = new InitialLdapContext(env, null); 

     // find the account now that the user is authenticated to 
     // construct the UserEntity 
     // note: code for findAccountByAccountName() not included as 
     //  the creation of the context is what generates the 
     //  exception 
     return findAccountByAccountName(context, "<search-base>", username); 
    } 
    } 

Здесь это код, который создает нового пользователя

public static void addUser(@NotNull final String username, 
           @NotNull final String firstName, 
           @NotNull final String password) 
    throws NamingException 
    { 
    // Create a container set of attributes 
    // 
    Attributes container = new BasicAttributes(true); // case ignore 

    // Create the object class to add 
    Attribute objClasses = new BasicAttribute("objectClass"); 
    objClasses.add("top"); 
    objClasses.add("person"); 
    objClasses.add("organizationalPerson"); 
    objClasses.add("user"); 

    // Assign the username and first name 
    // 
    Attribute givenName = new BasicAttribute("givenName", firstName); 
    Attribute sAMAccountName = new BasicAttribute("sAMAccountName", username); 

    // Make the account active 
    // 
    Attribute userAccountControl = new BasicAttribute("userAccountControl", "512") ; 

    // Add these to the container 
    // 
    container.put(objClasses); 
    container.put(givenName); 
    container.put(sAMAccountName); 
    container.put(userAccountControl) ; 

    // only can do this if connecting via secure ldap 
    // 
    if (isSecureLdap()) 
    { 
     try 
     { 
      final String quotedPassword = String.format("\"%s\"", password) ; 
      Attribute pwd = new BasicAttribute("unicodePwd", quotedPassword.getBytes("UTF-16LE")); 
      container.put(pwd); 
     } 
     catch (UnsupportedEncodingException e) 
     { 
      LOGGER.error("Unable to encode password"); 
     } 
    } 

    // creates a context using the Admin credentials. 
    LdapContext context = setup() ; 

    // Create the entry 
    // 
    context.createSubcontext(getUserDN(username), container); 
} 

Тогда в сводке:

// authenticate a known user 
// 
try 
{ 
    // existing user 'dev' and this works just fine 
    authenticate("dev", "password") ; 
} 
catch (NamingException e) 
{ 
    // if authentication fails, which it does not in this case 
} 

// create new user 
// 
final String username = "myTestUser" ; 
final String password = "myTestPassword" ; 
try 
{ 
    addUser(username, "test", password) ; 
} 
catch (NamingException e) 
{ 
    // if creation fails, which it does not in this case 
} 

// try to find that user 
// 
try 
{ 
    // code for find() not included since it works 
    final UserEntity user = findUser(username) ; 
} 
catch (NoSuchUserException e) 
{ 
    // thrown by find() if it fails -- again, this part still works 
} 

// attempt to authenticate the newly created user 
// 
try 
{ 
     authenticate(username, password) ; 
} 
catch (NamingException e) 
{ 
    // this is the part that throws the exception 
} 

Я уверен, что это что-то незначительное, что не хватает, но после поиска вокруг совсем немного на так и в других местах, я не нашел волшебный боб, чтобы исправить это.

+1

В вашем домене AD есть несколько контроллеров домена? Если вы хотите немедленно использовать только что созданную учетную запись, вам необходимо убедиться, что она попала на тот же контроллер домена, поскольку учетная запись не будет реплицирована на другие контроллеры домена. –

+0

в нашей тестовой среде, мы работаем только с одним контроллером. –

ответ

0

Попробуйте использовать код для пароля:

private byte[] encodePassword(String pass) throws UnsupportedEncodingException 
{ 
    final String ATT_ENCODING = "Unicode"; 
    // Agree with MS's ATTRIBUTE_CONSTRAINT 
    String pwd = "\"" + pass +"\""; 
    byte bytes[] = pwd.getBytes(ATTENCODING); 
    // strip unicode marker 
    byte bytes[] = new byte [_bytes.length - 2]; 
    System.arraycopy(_bytes, 2, bytes, 0,_bytes.length - 2); 
    return bytes; 
} 

Microsoft Active Directory смешно о паролях. Обычно мы добавляем пользователя, а затем изменяем пароль. -jim

+0

Это необязательно. Это может быть проблема с репликацией. –

+0

Пробовал вышеуказанный код, но генерирует исключение WILL_NOT_PERFORM. Я попытался изменить «Unicode» на исходный UTF-16LE и получить тот же результат. Мой исходный код (из публикации) кажется успешным. –

+0

и «success», я имею в виду, что он создает пользователя. Тем не менее, он не может аутентифицироваться против этого пользователя. –