io.quarkus.elytron.security.ldap.QuarkusDirContextFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of quarkus-elytron-security-ldap Show documentation
Show all versions of quarkus-elytron-security-ldap Show documentation
Secure your applications with username/password via LDAP
The newest version!
package io.quarkus.elytron.security.ldap;
import java.time.Duration;
import java.util.Hashtable;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.ldap.InitialLdapContext;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import org.wildfly.security.auth.realm.ldap.DirContextFactory;
public class QuarkusDirContextFactory implements DirContextFactory {
// private static final ElytronMessages log = Logger.getMessageLogger(ElytronMessages.class, "org.wildfly.security");
private static final String CONNECT_TIMEOUT = "com.sun.jndi.ldap.connect.timeout";
private static final String READ_TIMEOUT = "com.sun.jndi.ldap.read.timeout";
public static final String INITIAL_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
private static final String SECURITY_AUTHENTICATION = "simple";
private final String providerUrl;
private final String securityPrincipal;
private final String securityCredential;
private final Duration connectTimeout;
private final Duration readTimeout;
private final ClassLoader targetClassLoader;
public QuarkusDirContextFactory(String providerUrl, String securityPrincipal, String securityCredential,
Duration connectTimeout, Duration readTimeout) {
this.providerUrl = providerUrl;
this.securityPrincipal = securityPrincipal;
this.securityCredential = securityCredential;
this.connectTimeout = connectTimeout;
this.readTimeout = readTimeout;
this.targetClassLoader = getClass().getClassLoader();
}
@Override
public DirContext obtainDirContext(ReferralMode mode) throws NamingException {
char[] charPassword = null;
if (securityCredential != null) { // password from String
charPassword = securityCredential.toCharArray();
}
return createDirContext(securityPrincipal, charPassword, mode);
}
@Override
public DirContext obtainDirContext(CallbackHandler handler, ReferralMode mode) throws NamingException {
NameCallback nameCallback = new NameCallback("Principal Name");
PasswordCallback passwordCallback = new PasswordCallback("Password", false);
try {
handler.handle(new Callback[] { nameCallback, passwordCallback });
} catch (Exception e) {
throw new RuntimeException("Could not obtain credential", e);
// throw log.couldNotObtainCredentialWithCause(e);
}
String securityPrincipal = nameCallback.getName();
if (securityPrincipal == null) {
throw new RuntimeException("Could not obtain principal");
// throw log.couldNotObtainPrincipal();
}
char[] securityCredential = passwordCallback.getPassword();
if (securityCredential == null) {
throw new RuntimeException("Could not obtain credential");
// throw log.couldNotObtainCredential();
}
return createDirContext(securityPrincipal, securityCredential, mode);
}
private DirContext createDirContext(String securityPrincipal, char[] securityCredential, ReferralMode mode)
throws NamingException {
final ClassLoader oldClassLoader = setClassLoaderTo(targetClassLoader);
try {
Hashtable env = new Hashtable<>();
env.put(InitialDirContext.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
env.put(InitialDirContext.PROVIDER_URL, providerUrl);
env.put(InitialDirContext.SECURITY_AUTHENTICATION, SECURITY_AUTHENTICATION);
if (securityPrincipal != null) {
env.put(InitialDirContext.SECURITY_PRINCIPAL, securityPrincipal);
}
if (securityCredential != null) {
env.put(InitialDirContext.SECURITY_CREDENTIALS, securityCredential);
}
env.put(InitialDirContext.REFERRAL, mode == null ? ReferralMode.IGNORE.getValue() : mode.getValue());
env.put(CONNECT_TIMEOUT, "" + connectTimeout.toMillis());
env.put(READ_TIMEOUT, "" + readTimeout.toMillis());
// if (log.isDebugEnabled()) {
// log.debugf("Creating [" + InitialDirContext.class + "] with environment:");
// env.forEach((key, value) -> log.debugf(" Property [%s] with value [%s]", key,
// key != InitialDirContext.SECURITY_CREDENTIALS ? Arrays2.objectToString(value) : "******"));
// }
InitialLdapContext initialContext;
try {
initialContext = new InitialLdapContext(env, null);
} catch (NamingException ne) {
// log.debugf(ne, "Could not create [%s]. Failed to connect to LDAP server.", InitialLdapContext.class);
throw ne;
}
// log.debugf("[%s] successfully created. Connection established to LDAP server.", initialContext);
return new DelegatingLdapContext(initialContext, this::returnContext, null);
} finally {
setClassLoaderTo(oldClassLoader);
}
}
@Override
public void returnContext(DirContext context) {
if (context == null) {
return;
}
if (context instanceof InitialDirContext) {
final ClassLoader oldClassLoader = setClassLoaderTo(targetClassLoader);
try {
context.close();
// log.debugf("Context [%s] was closed. Connection closed or just returned to the pool.", context);
} catch (NamingException ignored) {
} finally {
setClassLoaderTo(oldClassLoader);
}
}
}
private ClassLoader setClassLoaderTo(final ClassLoader targetClassLoader) {
final Thread currentThread = Thread.currentThread();
final ClassLoader original = currentThread.getContextClassLoader();
currentThread.setContextClassLoader(targetClassLoader);
return original;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy