docs: private User authcz(final Cache<AuthCredentials, User> cache, Cache<User, Set<String>> roleCache, final AuthCredentials ac,
              final AuthenticationBackend authBackend, final Set<AuthorizationBackend> authorizers) {
          if (ac == null) {
              return null;
          }
          try {
  
              //noop backend configured and no authorizers
              //that mean authc and authz was completely done via HTTP (like JWT or PKI)
              if (authBackend.getClass() == NoOpAuthenticationBackend.class && authorizers.isEmpty()) {
                  //no cache
                  return authBackend.authenticate(ac);
              }
  
              return cache.get(ac, new Callable<User>() {
                  @Override
                  public User call() throws Exception {
                      if (log.isTraceEnabled()) {
                          log.trace("Credentials for user " + ac.getUsername() + " not cached, return from " + authBackend.getType()
                                  + " backend directly");
                      }
                      final User authenticatedUser = authBackend.authenticate(ac);
                      authz(authenticatedUser, roleCache, authorizers);
  
                      return authenticatedUser;
                  }
              });
          } catch (Exception e) {
              if (log.isDebugEnabled()) {
                  log.debug("Can not authenticate " + ac.getUsername() + " due to " + e.toString(), e);
              }
              return null;
          } finally {
              ac.clearSecrets();
          }
      }