vt-middleware / ldaptive

A simple, extensible Java API for interacting with LDAP servers
56 stars 26 forks source link

SASL DIGEST-MD5 always throw UnsupportedCallbackException #234

Closed thanhquyen closed 1 year ago

thanhquyen commented 1 year ago

I am using CAS 6 with SASL DIGEST-MD5 but got issue as bellow. I also create a class to bind LDAP SASL use ldaptive v2.1.2 got the same issue. Please give advice. Thanks Exception in thread "main" java.lang.IllegalStateException: Could not initialize pool size for pool ldaptive-pool-1 at org.ldaptive.pool.AbstractConnectionPool.initialize(AbstractConnectionPool.java:516) at com.abc.ldap.ldaptest.AppMain.main(AppMain.java:25) Caused by: org.ldaptive.LdapException: SASL bind operation failed at org.ldaptive.transport.netty.NettyConnection.operation(NettyConnection.java:675) at org.ldaptive.BindConnectionInitializer.initialize(BindConnectionInitializer.java:177) at org.ldaptive.transport.netty.NettyConnection.open(NettyConnection.java:311) at org.ldaptive.transport.TransportConnection.strategyOpen(TransportConnection.java:171) at org.ldaptive.transport.TransportConnection.open(TransportConnection.java:83) at org.ldaptive.pool.AbstractConnectionPool.createConnection(AbstractConnectionPool.java:726) at org.ldaptive.pool.AbstractConnectionPool.lambda$createAvailableConnections$8(AbstractConnectionPool.java:768) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:829) Caused by: javax.security.sasl.SaslException: DIGEST-MD5: Cannot perform callback to acquire realm, authentication ID or password [Caused by javax.security.auth.callback.UnsupportedCallbackException] at java.security.sasl/com.sun.security.sasl.digest.DigestMD5Client.processChallenge(DigestMD5Client.java:369) at java.security.sasl/com.sun.security.sasl.digest.DigestMD5Client.evaluateChallenge(DigestMD5Client.java:220) at org.ldaptive.transport.DefaultSaslClient.bind(DefaultSaslClient.java:73) at org.ldaptive.transport.netty.NettyConnection.operation(NettyConnection.java:658) ... 12 more Caused by: javax.security.auth.callback.UnsupportedCallbackException at org.ldaptive.sasl.DigestMD5BindRequest.handle(DigestMD5BindRequest.java:98) at java.security.sasl/com.sun.security.sasl.digest.DigestMD5Client.processChallenge(DigestMD5Client.java:337) ... 15 more

dfish3r commented 1 year ago

I'm probably going to need to improve the logging to figure this out. What version of Java are you using?

thanhquyen commented 1 year ago

I am using Oracle JDK 11.0.12

dfish3r commented 1 year ago

Did you set a bind-dn and bind-credential? What does your configuration look like?

thanhquyen commented 1 year ago

CAS don't set bind-dn and bind-credential when using DIGEST-MD5. if (StringUtils.isNotBlank(properties.getSaslMechanism())) { LOGGER.debug("Creating LDAP SASL mechanism via [{}]", properties.getSaslMechanism());

        val bc = new BindConnectionInitializer();
        val sc = getSaslConfigFrom(properties);

        if (StringUtils.isNotBlank(properties.getSaslAuthorizationId())) {
            sc.setAuthorizationId(properties.getSaslAuthorizationId());
        }
        sc.setMutualAuthentication(properties.getSaslMutualAuth());
        if (StringUtils.isNotBlank(properties.getSaslQualityOfProtection())) {
            sc.setQualityOfProtection(QualityOfProtection.valueOf(properties.getSaslQualityOfProtection()));
        }
        if (StringUtils.isNotBlank(properties.getSaslSecurityStrength())) {
            sc.setSecurityStrength(SecurityStrength.valueOf(properties.getSaslSecurityStrength()));
        }
        bc.
        bc.setBindSaslConfig(sc);
        cc.setConnectionInitializers(bc);
    } else if (StringUtils.equals(properties.getBindCredential(), "*") && StringUtils.equals(properties.getBindDn(), "*")) {
        LOGGER.debug("Creating LDAP fast-bind connection initializer");
        cc.setConnectionInitializers(new FastBindConnectionInitializer());
    } else if (StringUtils.isNotBlank(properties.getBindDn()) && StringUtils.isNotBlank(properties.getBindCredential())) {
        LOGGER.debug("Creating LDAP bind connection initializer via [{}]", properties.getBindDn());
        cc.setConnectionInitializers(new BindConnectionInitializer(properties.getBindDn(), new Credential(properties.getBindCredential())));
    }

However, if I set bind-dn, credential, got another issue: resultCode=INVALID_CREDENTIALS, matchedDN=, diagnosticMessage=8009030C: LdapErr: DSID-0C09059A, comment: AcceptSecurityContext error, data 52e, v3839

Here is my code which using to binding: PooledConnectionFactory cf = PooledConnectionFactory.builder().config(ConnectionConfig.builder() .url("ldap://abc.xyz.com:389").useStartTLS(false) .connectionInitializers(BindConnectionInitializer.builder() .dn("sAMAccountName=admin,DC=xyz,DC=com") .credential(new Credential("bfR3V$21")) .saslConfig(SaslConfig.builder().mechanism(Mechanism.DIGEST_MD5).authorizationId("sAMAccountName=admin,DC=xyz,DC=com") .realm("XYZ.COM").qualityOfProtection(QualityOfProtection.AUTH) .mutualAuthentication(false).securityStrength(SecurityStrength.HIGH).build()) .build()) .build()).min(1).max(1).build(); cf.initialize(); // search operation performed as the test-principal user SearchOperation search = new SearchOperation(cf, "DC=xyz,DC=com"); SearchResponse response; try { response = search.execute("(sAMAccountName={user})"); LdapEntry entry = response.getEntry(); } catch (LdapException e) { // TODO Auto-generated catch block e.printStackTrace(); } cf.close();

dfish3r commented 1 year ago

I've never attempted digest-md5 against active directory. Since the server must have access to your clear text password (which is why this method of authentication should be avoided) it's possible that you must connect to the global catalog on port 3268/3269. That might explain why you're getting INVALID_CREDENTIALS. That's just a guess, hopefully your server logs can shed some light on the situation.

dfish3r commented 1 year ago

Created PRs for CAS: https://github.com/apereo/cas/pull/5705 https://github.com/apereo/cas/pull/5706

dfish3r commented 1 year ago

@thanhquyen can you provide anymore insight into this issue? If you have server logs you can share that may be helpful.

thanhquyen commented 1 year ago

@dfish3r Thanks for your support. I have changed some config in cas.properties and it was bind successfully.