@Override
  public Pair<SaslClientAuthenticationProvider, Token<? extends TokenIdentifier>>
    selectProvider(String clusterId, User user) {
    requireNonNull(clusterId, "Null clusterId was given");
    requireNonNull(user, "Null user was given");

    // Superfluous: we don't do SIMPLE auth over SASL, but we should to simplify.
    if (!User.isHBaseSecurityEnabled(conf)) {
      return new Pair<>(simpleAuth, null);
    }

    final Text clusterIdAsText = new Text(clusterId);

    // Must be digest auth, look for a token.
    // TestGenerateDelegationToken is written expecting DT is used when DT and Krb are both present.
    // (for whatever that's worth).
    for (Token<? extends TokenIdentifier> token : user.getTokens()) {
      // We need to check for two things:
      // 1. This token is for the HBase cluster we want to talk to
      // 2. We have suppporting client implementation to handle the token (the "kind" of token)
      if (
        clusterIdAsText.equals(token.getService()) && digestAuthTokenKind.equals(token.getKind())
      ) {
        return new Pair<>(digestAuth, token);
      }
    }
    // Unwrap PROXY auth'n method if that's what we have coming in.
    final UserGroupInformation currentUser = user.getUGI();
    // May be null if Hadoop AuthenticationMethod is PROXY
    final UserGroupInformation realUser = currentUser.getRealUser();
    if (
      currentUser.hasKerberosCredentials()
        || (realUser != null && realUser.hasKerberosCredentials())
    ) {
      return new Pair<>(krbAuth, null);
    }
    // This indicates that a client is requesting some authentication mechanism which the servers
    // don't know how to process (e.g. there is no provider which can support it). This may be
    // a bug or simply a misconfiguration of client *or* server.
    LOG.warn("No matching SASL authentication provider and supporting token found from providers"
      + " for user: {}", user);
    return null;
  }
Default implementation of {@link AuthenticationProviderSelector} which can choose from the
authentication implementations which HBase provides out of the box: Simple, Kerberos, and
Delegation Token authentication. This implementation will ignore any
{@link SaslAuthenticationProvider}'s which are available on the classpath or specified in the
configuration because HBase cannot correctly choose which token should be returned to a client
when multiple are present. It is expected that users implement their own
{@link AuthenticationProviderSelector} when writing a custom provider. This implementation is not
thread-safe. {@link #configure(Configuration, Collection)} and
{@link #selectProvider(String, User)} is not safe if they are called concurrently.
hbase-client/src/main/java/org/apache/hadoop/hbase/security/provider/BuiltInProviderSelector.java