sbt:未经授权发布到企业 Nexus 存储库

Posted

技术标签:

【中文标题】sbt:未经授权发布到企业 Nexus 存储库【英文标题】:sbt: publish to corporate Nexus repository unauthorized 【发布时间】:2013-05-01 19:06:07 【问题描述】:

快速解决

所需的凭据需要由 nexus 定义的确切领域。请参阅下面如何找到您定义的那个,但最肯定的是“Sonatype Nexus Repository Manager”。像往常一样将其余详细信息添加到凭据中。

c:/data/user/.sbt/.credentials

realm=Sonatype Nexus Repository Manager
host=nexus
user=repouser
password=password

build.sbt 凭据 += 凭据(Path.userHome / ".sbt" / ".credentials")

publishTo <<= version  v: String =>
  val nexus = "http://nexus/" 
  if (v.trim.endsWith("SNAPSHOT"))
    Some("snapshots" at nexus + "content/repositories/libs-snapshots")
  else
    Some("releases" at nexus + "content/repositories/libs-releases")
  

问题

我正在尝试将一个 jar 发布到公司关系存储库中。

我可以通过 Maven 完成这项工作,并且我已将存储库配置为能够使用 Nexus 提供内部 jar。但是,由于授权,发布失败。

> publish
[info] Packaging c:\app\target\scala-2.10\app_2.10-0.1-sources.jar ...
[info] Wrote D:\app\target\scala-2.10\app_2.10-0.1.pom
[info] :: delivering :: com.app#app_2.10;0.1 :: 0.1 :: release :: Tue May 07 18:28:44 BST     2013
[info] Done packaging.
[info]  delivering ivy file to D:\app\target\scala-2.10\ivy-0.1.xml
[info] Packaging D:\app\target\scala-2.10\app_2.10-0.1.jar ...
[info] Done packaging.
[trace] Stack trace suppressed: run last *:publish for the full output.
[error] (*:publish) java.io.IOException: Access to URL http://nexus/content/groups/common/com/app/app_2.10/0.1/app_2.10-0.1.pom was refused by the server: Unauthorized

c:/data/user/.sbt/.credentials

realm=X 
host=nexus
user=repouser
password=password

c:/data/user/.sbt/repositories

 [repositories]
  local
  x-repo: http://nexus/content/groups/common
  typesafe-ivy-releases: http://repo.typesafe.com/typesafe/ivy-releases/,     [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]   
  sbt-plugin-releases: http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases/
  maven-central

app/build.sbt

 name := "app"

 organization := "com.app"

 version := "0.1"

 scalaVersion := "2.10.1"

 libraryDependencies ++= Seq(
"org.scalatest" % "scalatest_2.10" % "2.0.M5b" % "test"
 )

 EclipseKeys.withSource := true

 publishMavenStyle := true

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

 publishTo := Some("X Maven Repo" at "http://nexus/content/groups/common")

我的 Maven settings.xml

 <mirrors>
 <mirror>
  <id>x-repo</id>
  <name>X Maven repo</name>
      <url>http://nexus/content/groups/common</url>
  <mirrorOf>*</mirrorOf>
 </mirror>
 </mirrors>

 <servers>
     <server>
       <id>x-repo</id>
       <username>repouser</username>
       <password>password</password>
     </server>
   </servers>

我已按照official doc 和其他各种帖子的说明进行操作,包括 ***,例如 one 或邮件列表,例如 this。没有工作。我已尝试启用额外的日志记录,但未提供更多详细信息。

我可以使用这个命令手动部署到 maven:

 mvn deploy:deploy-file -Durl=http://nexus/content/repositories/libs-snapshots -DrepositoryId=x-repo -DgroupId=com.app -DartifactId=app -Dpackaging=jar -Dversion=0.1-SNAPSHOT -Dfile=D:\app\target\scala-2.10\app_2.10-0.1.jar

尝试使用以下 publishTo,也没有运气

publishTo <<= version  v: String =>
  val nexus = "http://nexus/" 
  if (v.trim.endsWith("SNAPSHOT"))
    Some("snapshots" at nexus + "content/repositories/libs-snapshots")
  else
    Some("releases" at nexus + "content/repositories/libs-releases")
  

命令运行正常,直到需要授权,此时它们会失败。

凭证中的Realm,是对应maven中的Server Repository ID还是Name?要么不行,要么不行。

我一直在尝试为 Ivy 启用更多日志记录,但无法获得更多详细信息。

设置 ivyLoggingLevel := UpdateLogging.Full

据此,应该还有进一步的日志记录:

https://svn.apache.org/repos/asf/ant/ivy/core/tags/2.2.0/src/java/org/apache/ivy/util/url/IvyAuthenticator.java

我在内部代理后面,所以我需要设置 HTTP 用户和 HTTPS 用户和密码。也许是在这里被屏蔽了?

对如何提高 ivy 日志记录有什么建议吗?


更新

我有一些工作要做,使用 sbt-aether-deploy 插件,该插件使用 Maven 基础架构 (wagon) 进行部署。

凭据完全相同。事实上,领域似乎并不重要。

以下是使用的行:

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

publishTo <<= version  v: String =>
  val nexus = "http://nexus/"
    if (v.trim.endsWith("SNAPSHOT"))
    Some("snapshots" at nexus + "content/repositories/libs-snapshots")
  else 
    Some("releases" at nexus + "content/repositories/libs-releases")


seq(aetherSettings: _*)

seq(aetherPublishSettings: _*)

代理、ivy 和 nexus 之间有些问题。

我仍然会对使用 ivy 的建议感兴趣。


进一步更新:

使用

curl -X POST http://nexusUser:nexusPassword@nexus/content/repositories/libs-snapshots -v

我能够访问服务器。

指定要使用的代理的结果相同(它被配置为绕过本地网络,但某些 Java 进程(如 SBT)似乎需要标头)

当未指定 nexusUser:nexusPassword 时,我得到以下标题:

WWW-Authenticate: BASIC realm="Sonatype Nexus Repository Manager"

实际上这就是问题所在,凭据要求领域的名称是准确的标头,而不是像 maven 定义的其他自定义存储库名称。

非常感谢!

【问题讨论】:

【参考方案1】:

Ivy 使用 WWW-Authenticate 标头的领域,该标头必须逐字节匹配,等于您的凭据文件中配置的那个。

sbt-aether-deploy 使用相同的标头,但使用 Aether 作为其部署机制。常春藤没有。

确定 WWW-Authenticate 标头值的最简单方法是使用 cURL。

curl -X POST http://nexus/content/repositories/libs-snapshots -v > /dev/null

cURL 将提示您输入用户并通过。

-v 将增加详细信息,以便您能够看到请求和响应的标头。

【讨论】:

这里的另一个非常重要的注意事项是凭证文件中的主机需要只是 Nexus 服务器的 IP 或域名。如果您包含端口,它将不会选择凭据。【参考方案2】:

我怀疑您的凭据文件路径可能不正确。 尝试改变这个:

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

到那个:

credentials += Credentials("c:/data/user/.sbt/.credentials")

或先尝试直接排除故障:

credentials += Credentials("Sonatype Nexus Repository Manager", 
  "nexus.scala-tools.org", "admin", "admin123") 

如果这些不起作用,请检查您的凭据是否有效。

【讨论】:

我尝试过硬编码路径或直接在文件上使用凭据。它不起作用。

以上是关于sbt:未经授权发布到企业 Nexus 存储库的主要内容,如果未能解决你的问题,请参考以下文章

Jenkins 中的 Nexus 凭证与 sbt

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

为啥 Jfrog Artifactory 对具有匿名读取权限的工件返回 401 未经授权?

使用 Ivy-Ant 在 nexus 中发布工件:未经凭据授权?

无法将 Nexus 4 连接到 adb:未经授权

无法将Nexus 4连接到adb:未经授权