@Override
  protected String getUserDn(final String principal) throws IllegalArgumentException,
      IllegalStateException {
    String userDn;
    String matchedPrincipal = matchPrincipal(principal);
    String userSearchBase = getUserSearchBase();
    String userSearchAttributeName = getUserSearchAttributeName();

    // If not searching use the userDnTemplate and return.
    if ((userSearchBase == null || userSearchBase.isEmpty()) || (userSearchAttributeName == null
        && userSearchFilter == null && !"object".equalsIgnoreCase(userSearchScope))) {
      userDn = expandTemplate(userDnTemplate, matchedPrincipal);
      LOGGER.debug("LDAP UserDN and Principal: {},{}", userDn, principal);
      return userDn;
    }

    // Create the searchBase and searchFilter from config.
    String searchBase = expandTemplate(getUserSearchBase(), matchedPrincipal);
    String searchFilter;
    if (userSearchFilter == null) {
      if (userSearchAttributeName == null) {
        searchFilter = String.format("(objectclass=%1$s)", getUserObjectClass());
      } else {
        searchFilter = String.format("(&(objectclass=%1$s)(%2$s=%3$s))", getUserObjectClass(),
            userSearchAttributeName, expandTemplate(getUserSearchAttributeTemplate(),
                matchedPrincipal));
      }
    } else {
      searchFilter = expandTemplate(userSearchFilter, matchedPrincipal);
    }
    SearchControls searchControls = getUserSearchControls();

    // Search for userDn and return.
    LdapContext systemLdapCtx = null;
    NamingEnumeration<SearchResult> searchResultEnum = null;
    try {
      systemLdapCtx = getContextFactory().getSystemLdapContext();
      LOGGER.debug("SearchBase,SearchFilter,UserSearchScope: {},{},{}", searchBase, searchFilter, userSearchScope);
      searchResultEnum = systemLdapCtx.search(searchBase, searchFilter, searchControls);
      // SearchResults contains all the entries in search scope
      if (searchResultEnum.hasMore()) {
        SearchResult searchResult = searchResultEnum.next();
        userDn = searchResult.getNameInNamespace();
        LOGGER.debug("UserDN Returned,Principal: {},{}", userDn, principal);
        return userDn;
      } else {
        throw new IllegalArgumentException("Illegal principal name: " + principal);
      }
    } catch (AuthenticationException ne) {
      LOGGER.error("AuthenticationException in getUserDn", ne);
      throw new IllegalArgumentException("Illegal principal name: " + principal);
    } catch (NamingException ne) {
      throw new IllegalArgumentException("Hit NamingException: " + ne.getMessage());
    } finally {
      try {
        if (searchResultEnum != null) {
          searchResultEnum.close();
        }
      } catch (NamingException ne) {
        // Ignore exception on close.
      } finally {
        LdapUtils.closeContext(systemLdapCtx);
      }
    }
  }
@Test
  void testGetUserDn() {
    LdapRealm realm = new LdapRealm();

    // without a user search filter
    realm.setUserSearchFilter(null);
    assertEquals("foo ", realm.getUserDn("foo "));

    // with a user search filter
    realm.setUserSearchFilter("memberUid={0}");
    assertEquals("foo", realm.getUserDn("foo"));
  }