如何使用sbt访问已安全保护的Nexus?

49
我正在尝试访问需要基本身份验证的 Nexus 仓库管理器。从 Maven2 中一切正常,但是当我尝试在 SBT 中配置时,它无法找到工件。它使用自定义的存储库模式(请参见 此相关问题),但我认为这不应该成为问题。无论如何,相关配置在这里。

Project.scala:

val snapshotsName = "Repository Snapshots"
val snapshotsUrl = new java.net.URL("http://nexusHostIp:8081/nexus/content/repositories/snapshots")
val snapshotsPattern = "[organisation]/[module]/[revision]-SNAPSHOT/[artifact]-[revision](-[timestamp]).[ext]"
val snapshots = Resolver.url(snapshotsName, snapshotsUrl)(Patterns(snapshotsPattern))
Credentials(Path.userHome / ".ivy2" / ".credentials", log)

val dep = "group" % "artifact" % "0.0.1" extra("timestamp" -> "20101202.195418-3")

~/.ivy2/.credentials:

realm=Snapshots Nexus
host=nexusHostIp:8081
user=nexususername
password=nexuspassword

根据 SBT 用户组中的类似讨论,这应该可以正常工作,但是当我尝试构建时,我得到了以下内容。
==== Repository Snapshots: tried
[warn]    -- artifact group#artifact;0.0.1!artifact.jar:
[warn]    http://nexusHostIp:8081/nexus/content/repositories/snapshots/group/artifact/0.0.1-SNAPSHOT/artifact-0.0.1-20101202.195418-3.jar

我相当确定这是凭据问题,而不是其他问题,因为我可以直接访问它所说的URL并下载jar包(在身份验证后)。
我还尝试过像这样内联声明凭据(即使这不太理想):
Credentials.add("Repository Snapshots", "nexusHostIp", "nexususername", "nexuspassword")
6个回答

85

以下是我所做的事情(sbt 0.13 + artifactory - nexus 的安装过程应该类似):

1)按照此处所述编辑文件 ~/.sbt/repositories:http://www.scala-sbt.org/0.13.0/docs/Detailed-Topics/Proxy-Repositories.html

[repositories]
  local
  my-ivy-proxy-releases: http://repo.company.com/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
  my-maven-proxy-releases: http://repo.company.com/maven-releases/

2) 我锁定了我的Artifactory以禁用匿名访问。

3) 在~/.sbt/目录下创建了一个凭据文件.credentials

realm=Artifactory Realm
host=artifactory.mycompany.com
user=username
password=password

4) 创建一个文件,位于~/.sbt/0.13/plugins/credentials.sbt下,用于连接默认凭据

credentials += Credentials(Path.userHome / ".sbt" / ".credentials")

现在当我的项目加载时,sbt会像往常一样连接artifactory。

我这么做的原因是为了将存储库定义等内容从项目文件中分离出来,以便团队具有灵活性(他们可以设置内部服务器来提供正在进行的工件等)。

-Austen


12
如果使用Nexus,必须将领域配置为“Sonatype Nexus Repository Manager”。 - Wellingr
它对我有效,但我不明白如何在不指定端口的情况下使用“凭据”:我的Nexus实例正在侦听8082端口。 事实上,在“publishTo:=…”部分中我已经指定了端口。 我在这里错过了什么? - cirpo
当sbt根据build.properties进行更新时,它无法正常工作。 - Raman Yelianevich
为了解决这个问题,我已经将公共的ivy仓库添加到repositories文件中作为最后一个要检查的仓库:public-ivy-releases: https://repo.typesafe.com/typesafe/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext] - Raman Yelianevich
2
如果我在指定的文件夹中创建credentials.sbt,它不起作用,但如果我将其放在上一级文件夹中(~/.sbt/0.13/credentials.sbt),它就可以正常工作。 - László van den Hoek
显示剩余2条评论

35

更新:这个答案在最近的sbt版本中不起作用 - 请参考Austen的答案。

好了,我终于把这个问题解决了。

snapshotsName可以是任何值。在.credentials文件中的realm必须是当尝试访问存储库的URL时出现的HTTP身份验证领域(在我的情况下是nexus)。 realm也是Credentials.add的第一个参数。因此,该行应该是:

Credentials.add("Sonatype Nexus Repository Manager", "nexusHostIp", "nexususername", "nexuspassword")

主机名是指IP地址或DNS名称。因此,在.credentials中,host只是nexusHostIp,不包括端口号。

因此,有效的项目配置如下:

val snapshotsName = "Repository Snapshots"
val snapshotsUrl = new java.net.URL("http://nexusHostIp:8081/nexus/content/repositories/snapshots")
val snapshotsPattern = "[organisation]/[module]/[revision]-SNAPSHOT/[artifact]-[revision](-[timestamp]).[ext]"
val snapshots = Resolver.url(snapshotsName, snapshotsUrl)(Patterns(snapshotsPattern))
Credentials(Path.userHome / ".ivy2" / ".credentials", log)

val dep = "group" % "artifact" % "0.0.1" extra("timestamp" -> "20101202.195418-3")

使用类似以下内容的.credentials文件:

realm=Sonatype Nexus Repository Manager
host=nexusHostIp
user=nexususername
password=nexuspassword

"Sonatype Nexus Repository Manager"是HTTP认证领域。


7

根据SBT文档,有两种指定这样的存储库凭据的方法:

内联

credentials += Credentials("Some Nexus Repository Manager", "my.artifact.repo.net", "admin", "password123")

外部文件

credentials += Credentials(Path.userHome / ".ivy2" / ".credentials")

.credentials文件是一个属性文件,包含了realm、host、user和password等键值。例如:

realm=Some Nexus Repository Manager
host=my.artifact.repo.net
user=admin
password=password123

5
如果SBT启动器无法从代理服务器下载新版本的SBT,并且~/.sbt/boot/update.log显示您遇到了401身份验证错误,则可以使用环境变量SBT_CREDENTIALS指定ivy凭据文件的位置。以下任何一个都应该可以下载新的sbt版本:
  1. SBT_CREDENTIALS='/home/YOUR_USER_NAME/.ivy2/.credentials' sbt
  2. export SBT_CREDENTIALS="/home/YOUR_USER_NAME/.ivy2/.credentials"放入您的.bashrc(或.zshrc)中,启动新的shell会话,然后运行sbt
(您需要像其他答案中所示那样设置~/.ivy2/.credentials文件)
来源:https://github.com/sbt/sbt/commit/96e5a7957c830430f85b6b89d7bbe07824ebfc4b

2
检查所有包含凭据的文件。
对我而言,我在sbt 1.0中有一个新项目(而不是老旧的0.13),其中我有一个~/.sbt/1.0/global.sbt文件包含我的凭据,但我忘记了。因此,在必须更改密码后,artifactory下载被破坏并锁定了我的帐户。
如果可以轻松检查凭据和填充它们的文件链,那将很好。如果SBT先仔细检查身份验证/授权是否正确,然后再开始下载X个文件并在3次身份验证失败后锁定我的帐户,那也将很好。

2
这对我很有帮助。我正在使用SBT版本0.13.15:

~/.ivy2/.my-credentials(不带端口的主机):

realm=Sonatype Nexus Repository Manager
host=mynexus.mycompany.com
user=my_user
password=my_password

build.sbt(带端口的nexus url):

import sbt.Credentials

...

credentials += Credentials(Path.userHome / ".ivy2" / ".my-credentials")

...

resolvers in ThisBuild ++= Seq(
    MavenRepository("my-company-nexus", "https://mynexus.mycompany.com:8081/repository/maven-releases/")
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接