Поддерживает ли SBT упреждающую аутентификацию для загрузки пакетов?

Я использую SBT 1.2.8, и моему проекту необходимо загружать пакеты из репозитория на частном экземпляре Artifactory. Мое репо защищено базовой аутентификацией. Прочитав множество примеров и инструкций, я создал файл credentials.properties в своем репозитории.

realm=Artifactory Realm
host=artifactory.mycompany.com
username=my_username
password=my_password

Затем я добавил следующее в свой файл build.sbt

credentials += Credentials(new File("credentials.properties"))

Затем я добавил репозиторий в свой список распознавателей в resolvers.sbt.

"My Company Artifactory" at "https://artifactory.mycompany.com/artifactory/my_private_repo/",

Я создал свое приложение и смог нормально загрузить защищенные пакеты.

Однако системный администратор моей компании попросил меня включить параметр «Скрыть наличие несанкционированных ресурсов» в Artifactory. Этот параметр заставляет Artifactory возвращать ошибку 404, когда пользователь, не прошедший проверку подлинности, пытается получить доступ к защищенным ресурсам. Обычно в этом случае Artifactory возвращает 401 с заголовком WWW-Authenticate.

Внезапно мое приложение не смогло разрешить свои зависимости. Я отключил параметр Artifactory, а затем снова включил его и убедился, что этот параметр действительно является причиной моих проблем.

Похоже, что SBT не будет отправлять учетные данные, если он не будет оспорен заголовком 401 и WWW-Authenticate (с надлежащей областью). Глядя на документы и проблемы GitHub для SBT, Ivy и Coursier, кажется, что эта «упреждающая аутентификация» не поддерживается.

Я провожу много часов, пытаясь решить эту проблему различными способами, но не могу найти решение. Вот что я пробовал:

  • Добавление моего имени пользователя и пароля Artifactory к URL-адресу репозитория, чтобы он выглядел как https://my_username:[email protected]/artifactory/my_private_repo/. Это работало в моем браузере и клиенте REST, но не с SBT.
  • Исключение «области» из моего файла учетных данных
  • Переходим на SBT 1.3.9 и пробуем все вышеперечисленное с новой версией.

Кто-нибудь знает, как я могу заставить SBT использовать упреждающую базовую аутентификацию HTTP? Похоже, что и Maven, и Gradle поддерживают это (см. ссылки ниже), но я ничего не могу найти в документах SBT.

Поддержка упреждающей аутентификации Maven: https://jfrog.com/knowledge-base/why-does-my-maven-builds-are-failing-with-a-404-error-when-hide-existence.-of-unauthorized-resources-is-enabled/

Поддержка Gradle для упреждающей аутентификации: https://github.com/gradle/gradle/pull/386/files

Я почти подумываю настроить локальный прокси-сервер для отправки правильных заголовков Artifactory и указать SBT для использования локального прокси-сервера в качестве распознавателя. Однако это кажется излишне громоздким для разработчиков.


person Jon Gunter    schedule 15.05.2020    source источник


Ответы (1)


ты прав.

Вы можете настроить AbstractRepository. См. https://github.com/SupraFii/sbt-google-artifact-registry/blob/master/src/main/scala/ch/firsts/sbt/gar/ArtifactRegistryRepository.scala#L21 Например:

package ch.firsts.sbt.gar

import java.io.File
import java.util

import com.google.cloud.artifactregistry.wagon.ArtifactRegistryWagon
import org.apache.ivy.core.module.descriptor.Artifact
import org.apache.ivy.plugins.repository.AbstractRepository
import org.apache.maven.wagon.repository.Repository

class ArtifactRegistryRepository(repositoryUrl: String) extends AbstractRepository {
  val repo = new Repository("google-artifact-registry", repositoryUrl)
  val wagon = new ArtifactRegistryWagon()

  override def getResource(source: String): ArtifactRegistryResource = {
    val plainSource = stripRepository(source)
    wagon.connect(repo)
    ArtifactRegistryResource(repositoryUrl, plainSource, wagon.resourceExists(plainSource))
  }

  override def get(source: String, destination: File): Unit = {
    val adjustedSource = if (destination.toString.endsWith("sha1"))
      source + ".sha1"
    else if (destination.toString.endsWith("md5"))
      source + ".md5"
    else
      source

    wagon.connect(repo)
    wagon.get(adjustedSource, destination)
  }

  override def list(parent: String): util.List[String] = sys.error("Listing repository contents is not supported")

  override def put(artifact: Artifact, source: File, destination: String, overwrite: Boolean): Unit = {
    val plainDestination = stripRepository(destination)
    wagon.connect(repo)
    wagon.put(source, plainDestination)
  }

  private def stripRepository(fullName: String): String = fullName.substring(repositoryUrl.length + 1)

}
person Guillaume Massé    schedule 07.03.2021