// OSecuritySystem (via OServerSecurity)
  // Used for generating the appropriate HTTP authentication mechanism.
  public String getAuthenticationHeader(final String databaseName) {
    String header = null;

    // Default to Basic.
    if (databaseName != null)
      header = "WWW-Authenticate: Basic realm=\"OrientDB db-" + databaseName + "\"";
    else header = "WWW-Authenticate: Basic realm=\"OrientDB Server\"";

    if (isEnabled()) {
      synchronized (authenticatorsList) {
        StringBuilder sb = new StringBuilder();

        // Walk through the list of OSecurityAuthenticators.
        for (OSecurityAuthenticator sa : authenticatorsList) {
          if (sa.isEnabled()) {
            String sah = sa.getAuthenticationHeader(databaseName);

            if (sah != null && sah.trim().length() > 0) {
              // If we're not the first authenticator, then append "\n".
              if (sb.length() > 0) {
                sb.append("\n");
              }
              sb.append(sah);
            }
          }
        }

        if (sb.length() > 0) {
          header = sb.toString();
        }
      }
    }

    return header;
  }
  // OSecuritySystem (via OServerSecurity)
  public String authenticate(final String username, final String password) {
    try {
      // It's possible for the username to be null or an empty string in the case of SPNEGO Kerberos
      // tickets.
      if (username != null && !username.isEmpty()) {
        if (debug)
          OLogManager.instance()
              .info(
                  this,
                  "ODefaultServerSecurity.authenticate() ** Authenticating username: %s",
                  username);

        // This means it originates from us (used by openDatabase).
        if (username.equals(superUser) && password.equals(superUserPassword)) return superUser;
      }

      synchronized (authenticatorsList) {
        // Walk through the list of OSecurityAuthenticators.
        for (OSecurityAuthenticator sa : authenticatorsList) {
          if (sa.isEnabled()) {
            String principal = sa.authenticate(username, password);

            if (principal != null) return principal;
          }
        }
      }
    } catch (Exception ex) {
      OLogManager.instance()
          .error(this, "ODefaultServerSecurity.authenticate() Exception: %s", ex.getMessage());
    }

    return null; // Indicates authentication failed.
  }
  // OSecuritySystem (via OServerSecurity)
  // Indicates if the primary security mechanism supports single sign-on.
  public boolean isSingleSignOnSupported() {
    if (isEnabled()) {
      OSecurityAuthenticator priAuth = getPrimaryAuthenticator();

      if (priAuth != null) return priAuth.isSingleSignOnSupported();
    }

    return false;
  }
  // OServerSecurity
  public OSecurityAuthenticator getAuthenticator(final String authMethod) {
    if (isEnabled()) {
      synchronized (authenticatorsList) {
        for (OSecurityAuthenticator am : authenticatorsList) {
          // If authMethod is null or an empty string, then return the first OSecurityAuthenticator.
          if (authMethod == null || authMethod.isEmpty()) return am;

          if (am.getName() != null && am.getName().equalsIgnoreCase(authMethod)) return am;
        }
      }
    }

    return null;
  }
  // OSecuritySystem (via OServerSecurity)
  // This will first look for a user in the security.json "users" array and then check if a resource
  // matches.
  public boolean isAuthorized(final String username, final String resource) {
    if (isEnabled()) {
      if (username == null || resource == null) return false;

      if (username.equals(superUser)) return true;

      synchronized (authenticatorsList) {
        // Walk through the list of OSecurityAuthenticators.
        for (OSecurityAuthenticator sa : authenticatorsList) {
          if (sa.isEnabled()) {
            if (sa.isAuthorized(username, resource)) return true;
          }
        }
      }
    }

    return false;
  }
  // OServerSecurity
  public OServerUserConfiguration getUser(final String username) {
    OServerUserConfiguration userCfg = null;

    if (isEnabled()) {
      if (username.equals(superUser)) return superUserCfg;

      synchronized (authenticatorsList) {
        // Walk through the list of OSecurityAuthenticators.
        for (OSecurityAuthenticator sa : authenticatorsList) {
          if (sa.isEnabled()) {
            userCfg = sa.getUser(username);
            if (userCfg != null) break;
          }
        }
      }
    }

    return userCfg;
  }
  // OServerLifecycleListener Interface
  public void onBeforeDeactivate() {
    if (enabled) {
      unregisterRESTCommands();

      synchronized (importLDAPSynch) {
        if (importLDAP != null) {
          importLDAP.dispose();
          importLDAP = null;
        }
      }

      synchronized (passwordValidatorSynch) {
        if (passwordValidator != null) {
          passwordValidator.dispose();
          passwordValidator = null;
        }
      }

      synchronized (auditingSynch) {
        if (auditingService != null) {
          auditingService.dispose();
          auditingService = null;
        }
      }

      synchronized (authenticatorsList) {
        // Notify all the security components that the server is active.
        for (OSecurityAuthenticator sa : authenticatorsList) {
          sa.dispose();
        }

        authenticatorsList.clear();
      }

      enabled = false;
    }
  }
  private void loadAuthenticators(final ODocument authDoc) {
    synchronized (authenticatorsList) {
      for (OSecurityAuthenticator sa : authenticatorsList) {
        sa.dispose();
      }

      authenticatorsList.clear();

      if (authDoc.containsField("authenticators")) {
        List<ODocument> authMethodsList = authDoc.field("authenticators");

        for (ODocument authMethodDoc : authMethodsList) {
          try {
            if (authMethodDoc.containsField("name")) {
              final String name = authMethodDoc.field("name");

              // defaults to enabled if "enabled" is missing
              boolean enabled = true;

              if (authMethodDoc.containsField("enabled")) enabled = authMethodDoc.field("enabled");

              if (enabled) {
                Class<?> authClass = getClass(authMethodDoc);

                if (authClass != null) {
                  if (OSecurityAuthenticator.class.isAssignableFrom(authClass)) {
                    OSecurityAuthenticator authPlugin =
                        (OSecurityAuthenticator) authClass.newInstance();

                    authPlugin.config(server, serverConfig, authMethodDoc);
                    authPlugin.active();

                    authenticatorsList.add(authPlugin);
                  } else {
                    OLogManager.instance()
                        .error(
                            this,
                            "ODefaultServerSecurity.loadAuthenticators() class is not an OSecurityAuthenticator");
                  }
                } else {
                  OLogManager.instance()
                      .error(
                          this,
                          "ODefaultServerSecurity.loadAuthenticators() authentication class is null for %s",
                          name);
                }
              }
            } else {
              OLogManager.instance()
                  .error(
                      this,
                      "ODefaultServerSecurity.loadAuthenticators() authentication object is missing name");
            }
          } catch (Throwable ex) {
            OLogManager.instance()
                .error(this, "ODefaultServerSecurity.loadAuthenticators() Exception: ", ex);
          }
        }
      }
    }
  }