All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.vertx.ext.auth.ldap.impl.LdapAuthenticationImpl Maven / Gradle / Ivy

The newest version!
/********************************************************************************
 * Copyright (c) 2019 Stephane Bastian
 *
 * This program and the accompanying materials are made available under the 2
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0 3
 *
 * Contributors: 4
 *   Stephane Bastian - initial API and implementation
 ********************************************************************************/
package io.vertx.ext.auth.ldap.impl;

import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.internal.VertxInternal;
import io.vertx.ext.auth.User;
import io.vertx.ext.auth.authentication.CredentialValidationException;
import io.vertx.ext.auth.authentication.Credentials;
import io.vertx.ext.auth.authentication.UsernamePasswordCredentials;
import io.vertx.ext.auth.ldap.LdapAuthentication;
import io.vertx.ext.auth.ldap.LdapAuthenticationOptions;

import javax.naming.Context;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Objects;

/**
 * @author Stephane Bastian
 */
public class LdapAuthenticationImpl implements LdapAuthentication {
  private static final String SIMPLE_AUTHENTICATION_MECHANISM = "simple";
  private static final String FOLLOW_REFERRAL = "follow";

  private final Vertx vertx;
  private final LdapAuthenticationOptions authenticationOptions;

  public LdapAuthenticationImpl(Vertx vertx, LdapAuthenticationOptions authenticationOptions) {
    this.vertx = Objects.requireNonNull(vertx);
    this.authenticationOptions = Objects.requireNonNull(authenticationOptions);
  }

  @Override
  public Future authenticate(Credentials credentials) {
    final UsernamePasswordCredentials authInfo;
    try {
      try {
        authInfo = (UsernamePasswordCredentials) credentials;
      } catch (ClassCastException e) {
        throw new CredentialValidationException("Invalid credentials type", e);
      }
      authInfo.checkValid(null);
    } catch (RuntimeException e) {
      return Future.failedFuture(e);
    }

    String ldapPrincipal = getLdapPrincipal(authInfo.getUsername());
    return createLdapContext(ldapPrincipal, authInfo.getPassword())
      .compose(ldapContext -> {
        User user = User.fromName(authInfo.getUsername());
        // metadata "amr"
        user.principal().put("amr", Collections.singletonList("pwd"));
        return Future.succeededFuture(user);
      });
  }

  private Future createLdapContext(String principal, String credential) {
    Hashtable environment = new Hashtable<>();
    // set the initial cntext factory
    environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    // set the url
    environment.put(Context.PROVIDER_URL, authenticationOptions.getUrl());

    if (principal != null) {
      environment.put(Context.SECURITY_PRINCIPAL, principal);
    }
    if (credential != null) {
      environment.put(Context.SECURITY_CREDENTIALS, credential);
    }
    if (authenticationOptions.getAuthenticationMechanism() == null && (principal != null || credential != null)) {
      environment.put(Context.SECURITY_AUTHENTICATION, SIMPLE_AUTHENTICATION_MECHANISM);
    }
    // referral
    environment.put(Context.REFERRAL,
      authenticationOptions.getReferral() == null ? FOLLOW_REFERRAL : authenticationOptions.getReferral());

    Promise promise = ((VertxInternal) vertx).promise();

    vertx.executeBlocking(() -> new InitialLdapContext(environment, null)).onComplete(promise);

    return promise.future();
  }

  private String getLdapPrincipal(String principal) {
    return authenticationOptions.getAuthenticationQuery().replace("{0}", principal);
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy