Note: CCed the dev mailing, where it belongs to.

ApacheDS will simply store the password as provided, ie as a hash value prepended with {SHA}, base64 encoded. It knows nothing about the password, until someone tries to bind using this password. The check is done by the SimpleAuthenticator.authenticate() method, which iterate over the stored passwords, until it finds one match or none.

Matching the provided password with the stored password is done using the PasswordUtil.compareCredentials( credentials, storedPassword ) method. This method can be checked outside of the server, it's a util class and the method is static.

Can you check that the userPassword attribute values are containing one value that match the provided passsword ?


The log you provided shows that no value matches, which means either the provided clear text password is incorrect, or that the stored hashed password value is not present.


On 27/12/2018 23:15, Richard Sand wrote:
Hmm, not sure how that would be, since it works when the userpassword attribute in the LDIF is cleartext. When running the embedded DS with @ApplyLdifFiles({"test.ldif”}), doesn’t the DS recognize that the pwd attribute is already hashed if prepended with {SHA}?

On Dec 27, 2018, at 4:51 PM, Emmanuel Lecharny <[email protected] <mailto:[email protected]>> wrote:

Also it pop up in my mind that it may be a consequence of your cache changes ?

On Thu, Dec 27, 2018 at 7:17 AM Emmanuel Lécharny <[email protected] <mailto:[email protected]>> wrote:


    On 26/12/2018 23:23, Richard Sand wrote:
    > Thanks Emmanuel, I’m happy to help!
    >
    > By the way, at your suggestion, I changed my app to use
    Caffeine for
    > its in-memory cache - you’re right, it really is very trivial
    to use!
    > And it resolved the conflict with ehcache v2 vs v3 in the
    embedded DS.
    >
    > One other odd roadblock I’ve hit today - is getting the embedded
    > ApacheDS to authenticate simple binds when the test LDIF data has
    > hashed passwords.
    >
    > My LDIF file has:
    >
    > dn: uid=monkey,ou=Users,ou=SSORest Eval,o=IDF Connect,c=US
    > objectClass: inetOrgPerson
    > ...
    > uid: monkey
    > userpassword:: 0oH9vgVVuRPRwp+ZFDo617xmz4M=


    That won't work, because ApacheDS (or any other LDAP server) will
    have
    no clue about which hash function to use to hash the incoming
    password
    to compare it with the stored password.


    The way it works :

    -inject a hashed password with the used hash method

    - then when a user tries to bind, providing a clear text
    password, the
    server will pull the hashed password from the database, get the hash
    method from it, hash the provided password and compare it with the
    provided hashed password


    > I generated the above value by calling:
    >
    >   String storagePwd = new String(
    > PasswordUtil.createStoragePassword(
    > password.getBytes(StandardCharsets.UTF_8),
    > LdapSecurityConstants.HASH_METHOD_SHA
    > ), StandardCharsets.UTF_8);
    >
    >
    > But then when I do a simple bind in my unit test, I get the
    error message:
    >
    > [2018-12-26
    >
    15:05:09.179][pool-5-thread-1][INFO][][o.a.d.s.c.a.AbstractAuthenticator]

    > - [ERR_230 Password not correct for user
    > ‘uid=monkey,ou=Users,ou=SSORest Eval,o=IDF Connect,c=US']
    > [2018-12-26
    >
    
15:05:09.179][pool-5-thread-1][INFO][][o.a.d.s.c.a.AuthenticationInterceptor]

    > - [Authenticator
    >
    org.apache.directory.server.core.authn.SimpleAuthenticator@602fe822
    > failed to authenticate: uid=monkey,ou=Users,ou=SSORest Eval,o=IDF
    > Connect,c=US]
    > [2018-12-26
    >
    
15:05:09.179][pool-5-thread-1][INFO][][o.a.d.s.c.a.AuthenticationInterceptor]

    > - [Cannot bind to the server ]
    >
    > I seem to be stuck on something trivial. I also followed the
    sample
    > code invoking MessageDigest as per
    >
    
https://directory.apache.org/apacheds/basic-ug/3.1-authentication-options.html#but-how-to-obtain-the-hash-value-for-a-password

    > , but as expected it generated the same value as PasswordUtil…
    >
    > I’ve also tried specifying the attribute as:
    >
    > userpassword: {SHA}0oH9vgVVuRPRwp+ZFDo617xmz4M=


    It should definitively work. We have a unit test that verifies it
    works:


         @Test
         public void testSHA() throws Exception
         {
             apply( getService(), getUserAddLdif() );
             String userDn = "uid=akarasulu,ou=users,ou=system";
             LdapConnection connection = getConnectionAs( getService(),
    userDn, "test" );

             // Check that we can get the attributes

             Entry entry = connection.lookup( userDn );
             assertNotNull( entry );
             assertTrue( entry.get( "uid" ).contains( "akarasulu" ) );

             // now modify the password for akarasulu : 'secret',
    encrypted
    using SHA
             ModifyRequest modReq = new ModifyRequestImpl();
             modReq.setName( new Dn( getService().getSchemaManager(),
    userDn
    ) );
             modReq.replace( "userPassword",
    "{SHA}5en6G6MezRroT3XKqkdPOmY/BfQ=" );
             connection.modify( modReq );

             // close and try with old password (should fail)
             connection.close();

             try
             {
                 connection.bind( userDn, "test" );
                 fail();
             }
             catch ( LdapAuthenticationException lae )
             {
                 assertTrue( true );
             }

             // try again now with new password (should be successful)
             connection.bind( userDn, "secret" );
             assertTrue( connection.isAuthenticated() );
    ...


    Are you 100% sure the password you try to bind with is the one
    you hashed ?




--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com <http://www.iktek.com/>

Reply via email to