如何禁用阻塞外部 HTTP 存储库的 maven?

自3.8.1版以来,Maven 默认阻止外部 HTTP 存储库(参见 https://maven.apache.org/docs/3.8.1/release-notes.html)

有没有办法禁用这个规则,或者让存储库免受这个规则的影响?

142164 次浏览

通过检查 Maven git 存储库中负责默认 HTTP 阻塞的提交,我找到了解决方案: https://github.com/apache/maven/commit/907d53ad3264718f66ff15e1363d76b07dd0c05f

我的解决办法如下:

在 Maven 设置(位于 ${maven.home}/conf/settings.xml${user.home}/.m2/settings.xml)中,必须删除以下条目:

<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
</mirror>

如果您在一个项目中工作,并且不能确保 Maven 设置始终如此,例如,因为您与其他人共享代码或者希望使用自动测试的 CI/CD,您可以执行以下 : 在项目中添加一个名为 .mvn的目录。在 .mvn目录中,添加一个名为 maven.config的文件,其内容为 --settings ./.mvn/local-settings.xml。在 .mvn目录中,添加一个名为 local-settings.xml的文件。这个文件应该是这样的:

<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 http://maven.apache.org/xsd/settings-1.2.0.xsd">
<mirrors>
<mirror>
<id>my-repository-http-unblocker</id>
<mirrorOf>my-blocked-http-repository</mirrorOf>
<name></name>
<url>http://........</url>
</mirror>
</mirrors>
</settings>

<mirrorOf>标记中,需要指定阻塞存储库的 id,在 <url>标记中,需要再次指定存储库的原始 URL。您需要为您拥有的每个被阻塞的存储库创建这个解除阻塞镜像。

例如:

如果在 pom.xml中定义了以下 HTTP 存储库:

<repositories>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>libs-release</name>
<url>http://my-url/libs-release</url>
</repository>
<repository>
<id>snapshots</id>
<name>libs-snapshot</name>
<url>http://my-url/libs-snapshot</url>
</repository>
</repositories>

然后你需要在 .mvn/local-settings.xml:

<settings>
<mirrors>
<mirror>
<id>release-http-unblocker</id>
<mirrorOf>central</mirrorOf>
<name></name>
<url>http://my-url/libs-release</url>
</mirror>
<mirror>
<id>snapshot-http-unblocker</id>
<mirrorOf>snapshots</mirrorOf>
<name></name>
<url>http://my-url/libs-snapshot</url>
</mirror>
</mirrors>
</settings>

我希望我的工作可以帮助其他偶然发现这一点的人。但是,如果你有一个更优雅或更好的解决方案,请分享!

另一个可能的解决方案是覆盖新的默认 http 阻塞行为,在专家的“ main”settings.xml文件的 <mirrors>部分注释掉 maven-default-http-blocker镜像(在我的例子中是在 /opt/maven/conf下) ;

<!--mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>false</blocked>
</mirror-->

另外,解除所有保险的 http 存储库的阻塞是否是一个好主意完全是另外一回事。

您只需要向 http 存储库添加一个镜像,允许在 Maven 设置中使用 http。您不应该消除所有存储库的默认 maven 行为。然后告诉 Devops 团队使用 https!

.m2/settings.xml:

<mirrors>
<mirror>
<id>my-repo-mirror</id>
<name>My Repo HTTP Mirror</name>
<url>http://url-to.my/repo</url>
<mirrorOf>my-repo</mirrorOf>
</mirror>
</mirrors>

在我的例子中,我只是添加了一个 id 为 maven-default-http-blocker的虚拟镜像来覆盖现有的镜像。这将禁用所有存储库的 HTTP 阻塞。

<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 http://maven.apache.org/xsd/settings-1.2.0.xsd">
<mirrors>
<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>dummy</mirrorOf>
<name>Dummy mirror to override default blocking mirror that blocks http</name>
<url>http://0.0.0.0/</url>
</mirror>
</mirrors>
</settings>

您可以遵循 Maven 文档中的官方建议,它在与您分享的相同链接中进行了解释: https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked

需要解决的问题包括:
  • 将依赖项版本升级到替换了 过时的 HTTP 存储库 URL,使用 HTTPS,

  • 保留依赖项版本,但在设置中定义镜像。

它包含一个到 Maven-镜像设置指南的链接

正如其他人提到的,不应重写默认安全设置。

一个有点不同的解决方案帮助了我,它更多地与我们的企业环境相关,并且涉及到这样一个事实: 我们正在慢慢地从 maven 转移到另一个 dep/build 工具,但是仍然定义了一个“企业”settings.xml文件。

所以只要将它重命名为一个不同的文件(而不是删除) ,比如 mv settings.xml settings-backup.xml,再次返回 maven 将帮助您检查是否存在问题。

在蒙特雷的 macOS 系统中,使用 Intellij Ultimate 2021.3(及以上版本) ,系统中没有安装 maven,在 Intellij 中使用 maven 作为插件,我在路径中找到了“ setings.xml”文件:

${user.home}/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/213.5744.223/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/conf/settings.xml

注意: < em > 上面的路径是当 Intellij 是使用 jetbrain 工具箱应用程序安装的时候,指定的版本号(213.5744.223)可以推迟,如果你有另一个版本,在访问该文件的路径时进行验证。

用你喜欢的编辑器打开“ setings.xml”文件,然后注释下面几行:

<!--<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>true</blocked>
</mirror>-->

希望有帮助。

解除特定 HTTP 存储库的阻塞

要解除某个特定存储库的阻塞,可以在设置中定义一个虚拟镜像,方法是添加一个 <mirror>,其 url相同,其 <mirrorOf>值与存储库的 id相匹配。不需要做任何改变就能成功。

例如:
如果你的回购标识是 团队内部回收,那么一个镜像添加到你的 ~/.m2/settings.xml可能看起来像这样:

<settings>
...
<!-- Add a mirror. -->
<mirrors>
<mirror>
<id>team-internal-repo-mirror</id>
<mirrorOf>team-internal-repo</mirrorOf> <!-- Must match repository id. -->
<name>Dummy mirror to unblock the team repo server</name>
<url>http://insecure-internal-server/repository/team-repo/</url>
<!-- <blocked>false</blocked> --> <!-- This is not needed, the mirror is unblocked by default. -->
</mirror>
</mirrors>


<!-- Existing profile does not need to change. -->
<profiles>
<profile>
<id>default_profile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>team-internal-repo</id>
<name>Dev Team Internal Artifacts</name>
<url>http://insecure-internal-server/repository/team-repo/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
...
</profile>
</profiles>
</settings>

这里不需要 <blocked>标记。其他用户评论说,这个标签破坏了旧版本的 maven。我测试了一个包含和不包含这个标签的 http 回购,它是双向工作的。(使用 maven 3.8.2进行测试。)

解除一个或多个显式回购协议的阻塞要好于全面解除所有 http 存储库的阻塞。这样做可能是个坏主意:

  • 这会带来更大的安全风险。Apache 做出这种更改是有原因的,OP: https://maven.apache.org/docs/3.8.1/release-notes.html#cve-2021-26291引用的发行说明中对此进行了讨论
  • 修改 Maven 安装的内部配置(例如,在 ABC0中的设置文件,而不是在 ~/.m2中的自己的设置文件)可能会在更新或重新安装未来版本的 Maven 时造成麻烦。如果该文件被覆盖,您的回购可能会突然再次被阻止。

我在安装新版本的 maven 时遇到了这个问题。通过重命名修复了这个问题。M2目录到任何类似目录。M2级,然后再运行 Maven。它将重新创建目录,缺点是它将重新下载新的。M2是空的。然后将 setings.xml 转移到新的。M2目录。

我还没有测试是否从旧版本复制存储库目录。M2到新的就可以了。

更新: 将存储库目录从 ~/. m2-old 复制到新的 ~/. m2并不会在之后运行 maven 时导致任何错误

有时,当您的本地版本 setings.xml 较低,而您的 maven 版本高于此时,那么删除此配置不能解决问题:

<mirrors>
<mirror>
<id>my-repository-http-unblocker</id>
<mirrorOf>my-blocked-http-repository</mirrorOf>
<name></name>
<url>http://........</url>
</mirror>

也许看看增加 <blocked>false</blocked>能否解决这个问题:

<mirrors>
<mirror>
<id>my-repository-http-unblocker</id>
<mirrorOf>my-blocked-http-repository</mirrorOf>
<name></name>
<url>http://your blocked url</url>
<blocked>false</blocked>
</mirror>
</mirrors>

我通过在. xml 文件(在我的例子中是 pom.xml)中用 "https"替换 "http"解决了这个问题。 这解决了我的错误。

MacOS Monterey 12.3.1和 IntelliJ 2022.1使用捆绑的 maven (3.8.1)也有同样的问题。这个解决方案与 MrBitwise 提出的解决方案类似,但是设置文件有一个不同的路径(它是嵌入在应用程序内容文件夹中的路径) :

/Applications/IntelliJ\ IDEA\ CE.app/Contents/plugins/maven/lib/maven3/conf/settings.xml

然后我注释了以下代码:

<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>true</blocked>
</mirror>

对于本地环境,最快的方法是在 .m2\settings.xml中将 blocked值从 true设置为 false

  <id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>false</blocked>
</mirror>

我可以通过注释代码来编译: 应用程序/IntelliJ IDEA.app/content/plugins/maven/lib/maven3/conf/setings.xml

    <!--<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>false</blocked>
</mirror>-->

简直就是在路中间编写代码 应用程序/IntelliJ IDEA.app/content/plugins/maven/lib/maven3/conf/setings.xml

使用依赖项和插件的最新版本。我在 com.sun.xml.ws 中也遇到过同样的问题,但是将它们的版本从3.8.3改为4.0.0就解决了这个问题。

解锁受密码保护的 HTTP 存储库

我不喜欢修改 IntelliJ 的全局 setings.xml (可能需要在每次更新后再次修复) ,解除阻塞所有 HTTP-repo 的方法对我不起作用——我猜是因为我们的 HTTP-repo 是受密码保护的。

对我来说,最终起作用的是一个镜像条目,它完全符合最初的回购协议:

  • 和回收人的身份一样。
  • 与回购相同的 URL (它只是一个假镜像)
  • MirrorOf 也有相同的 ID。
  • 当然设置为假。

因此,镜像完全镜像 HTTP 回购,没有其他-您需要一个镜像为每个 HTTP 回购。但由于镜像的 ID 与回购相同,“服务器”部分中涉及该回购的身份验证设置也适合镜像并允许访问。

 <mirror>
<id>repoId</id><!-- Must fit to serverID!!! (can be same as repoID) -->
<name>My Mirror</name>
<!-- URL of the mirror - in our case just the same as the repo itself. -->
<url>http://mvn-host/content/repositories/myrepo/</url>
<mirrorOf>repoId</mirrorOf><!-- Mirrors exactly the repo itself -->
<blocked>false</blocked><!-- Unblock http access - only works in mirrors, and that's why we need a mirror. -->
</mirror>

所有这一切的关键在于,如果镜像受到保护,那么它需要一个服务器条目。