Exemplo n.º 1
0
    private Entry lookupUser(String username) throws LdapException {
      StringBuilder userQuery = new StringBuilder();
      userQuery.append("(&(objectclass=user)(|");
      boolean hasCondition = false;
      for (String lookupAttr : lookupAttrs) {
        String attrName = lookupAttr.trim();
        if (!attrName.isEmpty()) {
          userQuery.append('(').append(attrName).append('=').append(username).append(')');
          hasCondition = true;
        }
      }
      userQuery.append("))");

      if (!hasCondition) {
        return null;
      }

      logger.debug("LDAP user query " + userQuery.toString());

      EntryCursor responseCursor =
          connection.search(userDn, userQuery.toString(), SearchScope.SUBTREE);
      try {
        try {
          if (responseCursor != null && responseCursor.next()) {
            Entry match = responseCursor.get();
            logger.debug("LDAP user query result: " + match.getDn());
            return match;
          }
        } catch (CursorException e) {
          logger.debug("LDAP search error", e);
          return null;
        }
      } finally {
        responseCursor.close();
      }
      return null;
    }
  @Override
  public User authenticate(final AuthCredentials authCreds) throws AuthException {

    LdapConnection ldapConnection = null;
    final String user = authCreds.getUsername();

    final char[] password = authCreds.getPassword();
    authCreds.clear();

    EntryCursor result = null;

    try {

      ldapConnection = LDAPAuthorizator.getConnection(settings);

      final String bindDn = settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_BIND_DN, null);

      if (bindDn != null) {
        ldapConnection.bind(
            bindDn, settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_PASSWORD, null));
      } else {
        ldapConnection.anonymousBind();
      }

      result =
          ldapConnection.search(
              settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_USERBASE, ""),
              settings
                  .get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_USERSEARCH, "(sAMAccountName={0})")
                  .replace("{0}", user),
              SearchScope.SUBTREE);

      if (!result.next()) {
        throw new AuthException("No user " + user + " found");
      }

      final Entry entry = result.get();
      final String dn = entry.getDn().toString();

      if (result.next()) {
        throw new AuthException("More than one user found");
      }

      log.trace("Disconnect {}", bindDn == null ? "anonymous" : bindDn);

      SecurityUtil.unbindAndCloseSilently(ldapConnection);
      ldapConnection = LDAPAuthorizator.getConnection(settings);

      log.trace("Try to authenticate dn {}", dn);

      ldapConnection.bind(dn, new String(password));

      final String usernameAttribute =
          settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_USERNAME_ATTRIBUTE, null);
      String username = dn;

      if (usernameAttribute != null && entry.get(usernameAttribute) != null) {
        username = entry.get(usernameAttribute).getString();
      }

      log.debug("Authenticated username {}", username);

      return new LdapUser(username, entry);

    } catch (final Exception e) {
      log.error(e.toString(), e);
      throw new AuthException(e);
    } finally {
      if (result != null) {
        result.close();
      }

      SecurityUtil.unbindAndCloseSilently(ldapConnection);
    }
  }
Exemplo n.º 3
0
  public static LdapConnection getConnection(final Settings settings)
      throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
          FileNotFoundException, IOException, LdapException {
    final boolean useSSL =
        settings.getAsBoolean(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_LDAPS_SSL_ENABLED, false);
    final boolean useStartSSL =
        settings.getAsBoolean(
            ConfigConstants.ARMOR_AUTHENTICATION_LDAP_LDAPS_STARTTLS_ENABLED, false);
    final LdapConnectionConfig config = new LdapConnectionConfig();

    if (useSSL || useStartSSL) {
      // ## Truststore ##
      final KeyStore ts =
          KeyStore.getInstance(
              settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_LDAPS_TRUSTSTORE_TYPE, "JKS"));
      ts.load(
          new FileInputStream(
              new File(
                  settings.get(
                      ConfigConstants.ARMOR_AUTHENTICATION_LDAP_LDAPS_TRUSTSTORE_FILEPATH, null))),
          settings
              .get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_LDAPS_TRUSTSTORE_PASSWORD, "changeit")
              .toCharArray());

      final TrustManagerFactory tmf =
          TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
      tmf.init(ts);

      config.setSslProtocol("TLS");
      config.setEnabledCipherSuites(SecurityUtil.ENABLED_SSL_CIPHERS);
      config.setTrustManagers(tmf.getTrustManagers());
    }

    config.setUseSsl(useSSL);
    config.setUseTls(useStartSSL);
    config.setTimeout(5000L); // 5 sec

    final String[] ldapHosts =
        settings.getAsArray(
            ConfigConstants.ARMOR_AUTHENTICATION_LDAP_HOST, new String[] {"localhost"});

    LdapConnection ldapConnection = null;

    for (int i = 0; i < ldapHosts.length; i++) {
      log.trace("Connect to {}", ldapHosts[i]);

      try {

        final String[] split = ldapHosts[i].split(":");

        config.setLdapHost(split[0]);

        if (split.length > 1) {
          config.setLdapPort(Integer.parseInt(split[1]));
        } else {
          config.setLdapPort(useSSL ? 636 : 389);
        }

        ldapConnection = new LdapNetworkConnection(config);
        ldapConnection.connect();
        if (!ldapConnection.isConnected()) {
          continue;
        } else {
          break;
        }

      } catch (final Exception e) {
        continue;
      }
    }

    if (ldapConnection == null || !ldapConnection.isConnected()) {
      throw new LdapException(
          "Unable to connect to any of those ldap servers " + Arrays.toString(ldapHosts));
    }

    return ldapConnection;
  }
Exemplo n.º 4
0
  protected Set<Entry> resolveNestedRoles(
      final Tuple<String, Dn> role, final LdapConnection ldapConnection, final String roleName)
      throws AuthException, LdapException {

    EntryCursor rolesResult = null;
    EntryCursor _result = null;
    try {

      final Set<Entry> result = new HashSet<Entry>();
      Dn roleDn = null;
      final boolean isRoleStringValidDn = Dn.isValid(role.v1());

      if (role.v2() != null) {
        roleDn = role.v2();
      } else {
        // lookup role
        if (isRoleStringValidDn) {
          roleDn = ldapConnection.lookup(role.v1()).getDn();
        } else {

          try {

            // search
            _result =
                ldapConnection.search(
                    settings.get(
                        ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_ROLEBASE, ""),
                    settings
                        .get(
                            ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_ROLESEARCH,
                            "(member={0})")
                        .replace("{1}", role.v1()),
                    SearchScope.SUBTREE);

            // one
            if (!_result.next()) {
              log.warn("Cannot resolve role '{}' (NOT FOUND)", role.v1());
            } else {

              //
              final Entry entry = _result.get();
              roleDn = entry.getDn();

              if (_result.next()) {
                log.warn("Cannot resolve role '{}' (MORE THAN ONE FOUND)", role.v1());
              }
            }
          } catch (final CursorException e) {
            log.warn("Cannot resolve role '{}' (EXCEPTION: {})", e, role.v1(), e.toString());
          } finally {
            if (_result != null) {
              _result.close();
            }
          }
        }
      }

      log.trace("role dn resolved to {}", roleDn);

      rolesResult =
          ldapConnection.search(
              settings.get(ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_ROLEBASE, ""),
              settings
                  .get(
                      ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_ROLESEARCH,
                      "(member={0})")
                  .replace("{0}", roleDn == null ? role.v1() : roleDn.toString())
                  .replace("{1}", role.v1()),
              SearchScope.SUBTREE);

      for (final Iterator iterator = rolesResult.iterator(); iterator.hasNext(); ) {
        final Entry searchResultEntry = (Entry) iterator.next();
        final String _role = searchResultEntry.get(roleName).getString();
        log.trace("nested l1 {}", searchResultEntry.getDn());
        final Set<Entry> in =
            resolveNestedRoles(
                new Tuple<String, Dn>(_role, searchResultEntry.getDn()), ldapConnection, roleName);

        for (final Iterator<Entry> iterator2 = in.iterator(); iterator2.hasNext(); ) {
          final Entry entry = iterator2.next();
          result.add(entry);
          log.trace("nested l2 {}", entry.getDn());
        }

        result.add(searchResultEntry);
      }

      return result;
    } finally {

      if (rolesResult != null) {
        rolesResult.close();
      }
    }
  }
Exemplo n.º 5
0
  @Override
  public void fillRoles(final User user, final AuthCredentials optionalAuthCreds)
      throws AuthException {

    final String authenticatedUser = user.getName();

    if (optionalAuthCreds != null) {
      optionalAuthCreds.clear();
    }

    Entry entry = null;
    String dn = null;
    EntryCursor result = null;
    EntryCursor rolesResult = null;
    LdapConnection ldapConnection = null;

    try {

      ldapConnection = getConnection(settings);

      final String bindDn = settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_BIND_DN, null);

      if (bindDn != null) {
        ldapConnection.bind(
            bindDn, settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_PASSWORD, null));
      } else {
        ldapConnection.anonymousBind();
      }

      if (Dn.isValid(authenticatedUser)) {
        // assume dn
        log.trace("{} is a valid DN", authenticatedUser);
        entry = ldapConnection.lookup(authenticatedUser);

        if (entry == null) {
          throw new AuthException("No user '" + authenticatedUser + "' found");
        }

      } else {

        // TODO FUTURE all ldap searches: follow referrals
        result =
            ldapConnection.search(
                settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_USERBASE, ""),
                settings
                    .get(
                        ConfigConstants.ARMOR_AUTHENTICATION_LDAP_USERSEARCH,
                        "(sAMAccountName={0})")
                    .replace("{0}", authenticatedUser),
                SearchScope.SUBTREE);

        if (!result.next()) {
          throw new AuthException("No user '" + authenticatedUser + "' found");
        }

        entry = result.get();

        if (result.next()) {
          throw new AuthException("More than user found");
        }
      }

      dn = entry.getDn().toString();

      log.trace("User found with DN {}", dn);

      final Set<String> userRolesDn = new HashSet<String>();

      // Roles as an attribute of the user entry
      // Role names may also be held as the values of an attribute in the user's directory entry.
      // Use userRoleName to specify the name of this attribute.
      final String userRoleName =
          settings.get(
              ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_USERROLENAME, "memberOf");
      if (entry.get(userRoleName) != null) {
        final Value[] userRoles =
            Iterators.toArray(entry.get(userRoleName).iterator(), Value.class);

        for (int i = 0; i < userRoles.length; i++) {
          final Value value = userRoles[i];
          final String possibleRoleDN = value.getString();
          if (Dn.isValid(possibleRoleDN)) {
            userRolesDn.add(possibleRoleDN);
          }
        }

        log.trace("User roles count: {}", userRolesDn.size());
      }

      final Map<Tuple<String, Dn>, Entry> roles = new HashMap<Tuple<String, Dn>, Entry>();
      final String roleName =
          settings.get(ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_ROLENAME, "name");

      // replace {2}
      final String userRoleAttribute =
          settings.get(
              ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_USERROLEATTRIBUTE, null);
      String userRoleAttributeValue = null;

      if (userRoleAttribute != null) {
        userRoleAttributeValue =
            entry.get(userRoleAttribute) == null ? null : entry.get(userRoleAttribute).getString();
      }

      rolesResult =
          ldapConnection.search(
              settings.get(ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_ROLEBASE, ""),
              settings
                  .get(
                      ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_ROLESEARCH,
                      "(member={0})")
                  .replace("{0}", dn)
                  .replace("{1}", authenticatedUser)
                  .replace("{2}", userRoleAttributeValue == null ? "{2}" : userRoleAttributeValue),
              SearchScope.SUBTREE);

      for (final Iterator iterator = rolesResult.iterator(); iterator.hasNext(); ) {
        final Entry searchResultEntry = (Entry) iterator.next();
        roles.put(
            new Tuple<String, Dn>(searchResultEntry.getDn().toString(), searchResultEntry.getDn()),
            searchResultEntry);
      }

      log.trace("non user roles count: {}", roles.size());

      for (final Iterator<String> it = userRolesDn.iterator(); it.hasNext(); ) {
        final String stringVal = it.next();
        // lookup
        final Entry userRole = ldapConnection.lookup(stringVal);
        roles.put(new Tuple<String, Dn>(stringVal, null), userRole);
      }

      // nested roles
      if (settings.getAsBoolean(
          ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_RESOLVE_NESTED_ROLES, false)) {

        log.trace("Evaluate nested roles");

        final Set<Entry> nestedReturn = new HashSet<Entry>(roles.values());

        for (final Iterator<java.util.Map.Entry<Tuple<String, Dn>, Entry>> iterator =
                roles.entrySet().iterator();
            iterator.hasNext(); ) {
          final java.util.Map.Entry<Tuple<String, Dn>, Entry> _entry = iterator.next();

          final Set<Entry> x = resolveNestedRoles(_entry.getKey(), ldapConnection, roleName);

          log.trace("{}. nested roles for {} {}", x.size(), _entry.getKey(), roleName);

          nestedReturn.addAll(x);
        }

        for (final Iterator iterator = nestedReturn.iterator(); iterator.hasNext(); ) {
          final Entry entry2 = (Entry) iterator.next();
          final String role = entry2.get(roleName).getString();
          user.addRole(role);
        }

        if (user instanceof LdapUser) {
          ((LdapUser) user).addRoleEntries(nestedReturn);
        }

      } else {

        for (final Iterator iterator = roles.values().iterator(); iterator.hasNext(); ) {
          final Entry entry2 = (Entry) iterator.next();
          final String role = entry2.get(roleName).getString();
          user.addRole(role);
        }

        if (user instanceof LdapUser) {
          ((LdapUser) user).addRoleEntries(roles.values());
        }
      }

    } catch (final Exception e) {
      log.error(e.toString(), e);
      throw new AuthException(e);
    } finally {
      if (result != null) {
        result.close();
      }

      if (rolesResult != null) {
        rolesResult.close();
      }

      SecurityUtil.unbindAndCloseSilently(ldapConnection);
    }
  }
Exemplo n.º 6
0
 @Override
 public void close() throws IOException {
   connection.close();
 }
Exemplo n.º 7
0
 private Entry getUser(String cn) throws LdapException {
   return connection.lookup(cn);
 }