SBT 是不是支持下载包的抢先验证?

Posted

技术标签:

【中文标题】SBT 是不是支持下载包的抢先验证?【英文标题】:Does SBT to support preemptive auth for downloading packages?SBT 是否支持下载包的抢先验证? 【发布时间】:2020-09-01 14:03:36 【问题描述】:

我正在运行 SBT 1.2.8,我的项目需要从私有托管的 Artifactory 实例上的 repo 下载包。我的仓库受基本身份验证保护。在阅读了大量示例和说明后,我在我的仓库中创建了一个 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 会返回带有 WWW-Authenticate 标头的 401。

突然间,我的应用程序无法解析其依赖关系。我关闭了 Artifactory 设置,然后再次打开,并验证此设置实际上是我的问题的原因。

似乎 SBT 不会发送凭据,除非它受到 401 和 WWW-Authenticate 标头(使用正确的领域)的挑战。查看 SBT、Ivy 和 Coursier 的文档和 GitHub 问题,这种“抢先式身份验证”似乎不受支持。

我花了很多时间尝试以各种方式解决这个问题,但我找不到解决方案。这是我尝试过的:

将我的 Artifactory 用户名和密码添加到存储库 url,所以它看起来像 https://my_username:my_password@artifactory.mycompany.com/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 使用本地代理作为解析器。但是,对于开发人员来说,这似乎是不必要的麻烦。

【问题讨论】:

您是否设法找到了可行的解决方案/解决方法? 【参考方案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)


【讨论】:

以上是关于SBT 是不是支持下载包的抢先验证?的主要内容,如果未能解决你的问题,请参考以下文章

sbt-native-package docker 插件是不是支持创建标签

SBT 不支持自定义解析器

Scala/SBT:“对象不是包的成员”,但对象在外部库中

抢先 | 支持sql的Elasticsearch6.3全景概览

抢先一步,Rust构建版支持直接编译WebAssembly

[转帖]抢先AMD一步,英特尔推出新处理器,支持LPDDR5!