private Authorization authenticate(
      @Nullable Credential credential, Map<String, String> repositoryScopes)
      throws RegistryAuthenticationFailedException, RegistryCredentialsNotSentException {
    String registryUrl = registryEndpointRequestProperties.getServerUrl();
    String imageName = registryEndpointRequestProperties.getImageName();
    try {
      URL url = getAuthenticationUrl(credential, repositoryScopes);

      Request.Builder requestBuilder =
          Request.builder()
              .setHttpTimeout(JibSystemProperties.getHttpTimeout())
              .setUserAgent(userAgent);

      if (isOAuth2Auth(credential)) {
        String parameters = getAuthRequestParameters(credential, repositoryScopes);
        requestBuilder.setBody(
            new BlobHttpContent(Blobs.from(parameters), MediaType.FORM_DATA.toString()));
      } else if (credential != null) {
        requestBuilder.setAuthorization(
            Authorization.fromBasicCredentials(credential.getUsername(), credential.getPassword()));
      }

      String httpMethod = isOAuth2Auth(credential) ? HttpMethods.POST : HttpMethods.GET;
      try (Response response = httpClient.call(httpMethod, url, requestBuilder.build())) {

        AuthenticationResponseTemplate responseJson =
            JsonTemplateMapper.readJson(response.getBody(), AuthenticationResponseTemplate.class);

        if (responseJson.getToken() == null) {
          throw new RegistryAuthenticationFailedException(
              registryUrl,
              imageName,
              "Did not get token in authentication response from "
                  + getAuthenticationUrl(credential, repositoryScopes)
                  + "; parameters: "
                  + getAuthRequestParameters(credential, repositoryScopes));
        }
        return Authorization.fromBearerToken(responseJson.getToken());
      }

    } catch (ResponseException ex) {
      if (ex.getStatusCode() == HttpStatusCodes.STATUS_CODE_UNAUTHORIZED
          && ex.requestAuthorizationCleared()) {
        throw new RegistryCredentialsNotSentException(registryUrl, imageName);
      }
      throw new RegistryAuthenticationFailedException(registryUrl, imageName, ex);

    } catch (IOException ex) {
      throw new RegistryAuthenticationFailedException(registryUrl, imageName, ex);
    }
  }
Sends the authentication request and retrieves the Bearer authorization token.

@param credential the credential used to authenticate
@param scope the scope of permissions to authenticate for
@return the {@link Authorization} response
@throws RegistryAuthenticationFailedException if authentication fails
@throws RegistryCredentialsNotSentException if authentication is failed and credentials were
    not sent over plain HTTP
@see <a
    href="https://docs.docker.com/registry/spec/auth/token/#how-to-authenticate">https://docs.docker.com/registry/spec/auth/token/#how-to-authenticate</a>
jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryAuthenticator.java