更新 11/14:我通过运营团队验证了通过Active Directory用户界面登录时用户名/密码是否有效。因此,它只是以编程方式失败。
我正在使用一个简单的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
}
我确信这是一个很小的东西,但是在SO和其他地方搜索了很多东西之后,我还没有找到魔法豆来解决这个问题。
答案 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