@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);
    }
  }
Ejemplo n.º 2
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);
    }
  }