Using Maven Behind a Proxy – 在代理服务器后面使用Maven

最后修改: 2019年 12月 15日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

In this tutorial, we’re going configure Maven to work behind a proxy – a common situation in environments where we don’t connect directly to the internet.

在本教程中,我们将配置Maven,使其在代理后工作–这是我们不直接连接互联网的环境中的常见情况。

In our example, our proxy is running on the machine ‘proxy.baeldung.com’ and it listens for proxy requests via HTTP on port ’80’. We’ll also use some internal sites at internal.baeldung.com where we don’t need to go through a proxy.

在我们的例子中,我们的代理运行在机器上’proxy.baeldung.com’,它通过HTTP的端口’80’监听代理请求。我们还将使用一些内部网站internal.baeldung.com,我们不需要通过代理。

2. Proxy Configuration

2.代理人配置

First, let’s set up a basic proxy configuration without any credentials.

首先,让我们设置一个没有任何凭证的基本代理配置

Let’s edit our Maven settings.xml usually found in our ‘<user_home>/.m2′ directory. If there isn’t one there yet, then we can copy it from the global settings at ‘<maven_home>/conf’ directory.

让我们编辑我们的Maven settings.xml,通常在我们的’<user_home>/.m2′目录下找到。如果那里还没有,那么我们可以从’<maven_home>/conf’目录下的全局设置中复制它。

And now let’s create a <proxy> entry inside the <proxies> section:

现在让我们在<proxy>部分里面创建一个<proxy>条目。

<proxies>
   <proxy>
        <host>proxy.baeldung.com</host>
        <port>80</port>
    </proxy>
</proxies>

Since we also use a local site that doesn’t need to go through the proxy, let’s specify it in <nonProxyHosts> using a ‘|’ separated list with our localhost:

由于我们还使用了一个不需要通过代理的本地站点,让我们在<nonProxyHosts>中用’|’分隔的列表指定它与我们的本地主机。

<nonProxyHosts>internal.baeldung.com|localhost|127.*|[::1]</nonProxyHosts>

3. Adding Credentials

3.添加凭证

If our proxy wasn’t secured, that’s all we’d need; however, ours is, so let’s add our credentials to the proxy definition:

如果我们的代理不安全,这就是我们所需要的;然而,我们的代理是安全的,所以让我们在代理定义中添加我们的证书

<username>baeldung</username>
<password>changeme</password>

We don’t add username/password entries if we don’t need them – even empty ones – as having them present when the proxy doesn’t want them can cause our requests to be denied.

如果我们不需要用户名/密码条目,我们就不添加它们–甚至是空的–因为在代理不需要它们的时候出现它们会导致我们的请求被拒绝。

Our minimal authenticated configuration should now look like this:

我们最小的认证配置现在看起来应该是这样的。

<proxies>
   <proxy>
        <host>proxy.baeldung.com</host>
        <port>80</port>
        <username>baeldung</username>
        <password>changeme</password>
        <nonProxyHosts>internal.baeldung.com|localhost|127.*|[::1]</nonProxyHosts>
    </proxy>
</proxies>

Now, when we run the mvn command we’ll go through the proxy to connect to the sites we are after.

现在,当我们运行mvn命令时,我们将通过代理来连接到我们所要的网站。

3.1. Optional Entries

3.1.可选条目

Let’s give it the optional id of ‘BaeldungProxy_Authenticated’ to make it easier to reference, in case we ever need to switch proxies:

让我们给它一个可选的id,即’BaeldungProxy_Authenticated’,以便在我们需要切换代理时更容易引用。

<id>BaeldungProxy_Authenticated</id>

Now, if we have another proxy we can add another proxy definition, but only one can be active. By default, Maven will use the first active proxy definition it finds.

现在,如果我们有另一个代理,可以再添加一个代理定义,但只能有一个是活动的。默认情况下,Maven会使用它找到的第一个激活的代理定义

Proxy definitions are active by default, and get the implicit definition:

默认情况下,代理定义是激活的,并获得隐含的定义。

<active>true</active>

If we wanted to make another proxy the active one, then we’d de-activate our original entry by setting <active> to false:

如果我们想让另一个代理成为活动的代理,那么我们就通过设置<active>为false来取消我们原来的条目。

<active>false</active>

Maven’s default value for the proxy’s protocol is HTTP, which is suitable for most cases. If our proxy uses a different protocol, we’d declare it here and replace http with the protocol that our proxy needs:

Maven对代理协议的默认值是HTTP,这适用于大多数情况。如果我们的代理使用不同的协议,我们要在这里声明,并将http替换为我们代理需要的协议。

<protocol>http</protocol>

Note that this is the protocol the proxy uses – the protocol of our requests (ftp://, http://, https://) is independent of this.

注意,这是代理使用的协议–我们的请求(ftp://, http://, https://)的协议与此无关。

And here’s what our expanded proxy definition looks like, including the optional elements:

这就是我们扩展的代理定义的样子,包括可选元素。

<proxies>
   <proxy>
        <id>BaeldungProxy_Authenticated</id>
        <active>true</active>
        <protocol>http</protocol>
        <host>proxy.baeldung.com</host>
        <port>80</port>
        <username>baeldung</username>
        <password>changeme</password>
        <nonProxyHosts>internal.baeldung.com|localhost|127.*|[::1]</nonProxyHosts>
    </proxy>
</proxies>

So, that’s it for our basic proxy entry, but is it secure enough for us?

那么,这就是我们的基本代理条目,但它对我们来说足够安全吗?

4. Securing Our Configuration

4.确保我们的配置安全

Now, let’s say one of our colleagues wants us to send them our proxy configuration.

现在,假设我们的一个同事希望我们把我们的代理配置发给他们。

We’re not too keen on sending our password in plain text, so let’s see how easy Maven makes it to encrypt our passwords.

我们并不热衷于以纯文本形式发送密码,所以让我们看看Maven是如何轻松实现加密密码的

4.1. Creating a Master Password

4.1.创建一个主密码

First, let’s choose a master password, say “te!st!ma$ter”.

首先,让我们选择一个主密码,例如 “te!st!ma$ter”。

Now let’s encrypt our master password, by entering it at the prompt when we run:

现在,让我们对主密码进行加密,在运行时的提示符下输入密码。

mvn --encrypt-master-password
Master Password:

After we’ve pressed enter, we see our encrypted password enclosed between curly braces:

在我们按下回车键后,我们看到我们的加密密码被封闭在大括号内。

{QFMlh/6WjF8H9po9UDo0Nv18e527jqWb6mUgIB798n4=}

4.2. Troubleshooting Password Generation

4.2.密码生成的故障排除

If we see {} instead of the Master Password: prompt (this can happen when using bash), then we’ll need to specify the password on the command line.

如果我们看到的是{}而不是Master Password:提示(这在使用bash时可能发生),那么我们就需要在命令行上指定密码。

Let’s wrap the password in quotes to make sure any special characters like ‘!’ don’t have unwanted effects.

让我们用引号包住密码,以确保任何特殊字符如’!’不会产生不必要的影响。

So, let’s use single quotes if we’re using bash:

所以,如果我们使用bash的话,让我们使用单引号。

mvn --encrypt-master-password 'te!st!ma$ter'

Or use double-quotes if using a Windows command prompt:

如果使用Windows命令提示符,则使用双引号。

mvn --encrypt-master-password "te!st!ma$ter"

Now, sometimes our generated master password contains curly braces, like this example with a closing curly brace, ‘}’, after the ‘UD’:

现在,有时我们生成的主密码包含大括号,就像这个例子,在’UD’后面有一个闭合的大括号,’}’。

{QFMlh/6WjF8H9po9UD}0Nv18e527jqWb6mUgIB798n4=}

In this case, we can either:

在这种情况下,我们可以选择。

  • run the mvn –encrypt-master-password command again to generate another one (hopefully without a curly brace)
  • escape the curly braces in our password by adding a backslash in front of the ‘{‘ or }’

4.3. Creating a settings-security.xml File

4.3.创建一个settings-security.xml文件

Now let’s put our encrypted password, with an escaped ‘\}’, into a file called settings-security.xml file in our .m2 directory:

现在让我们把我们的加密密码,用转义的’/}’,放入我们的.m2目录下的一个叫settings-security.xml文件

<settingsSecurity>
    <master>{QFMlh/6WjF8H9po9UD\}0Nv18e527jqWb6mUgIB798n4=}</master>
</settingsSecurity>

Lastly, Maven lets us add a comment inside the master element.

最后,Maven让我们在主元素中添加一个注释。

Let’s add some text before the password ‘{‘ delimiter, taking care not to use a { or } in our comment as Maven uses them to find our password:

让我们在密码'{‘分隔符前添加一些文字,注意不要在注释中使用{或},因为Maven会用它们来寻找我们的密码。

<master>We escaped the curly brace with '\' {QFMlh/6WjF8H9po9UD\}0Nv18e527jqWb6mUgIB798n4=}</master>

4.4. Using a Removable Drive

4.4.使用可移动驱动器

Let’s say we need to be extra secure and want to store our master password on a separate device.

假设我们需要更加安全,希望将我们的主密码存储在一个单独的设备上

First, we’ll place our settings-security.xml file in a config directory on a removable drive, “R:”:

首先,我们将把我们的settings-security.xml文件放在一个可移动驱动器 “R: “上的配置目录中。

R:\config\settings-security.xml

And now, we’ll update the settings-security.xml file in our .m2 directory to redirect Maven to our real settings-security.xml on our removable drive:

现在,我们要更新.m2目录下的settings-security.xml文件,将Maven重定向到可移动硬盘上真正的settings-security.xml

<settingsSecurity>
    <relocation>R:\config\settings-security.xml</relocation>
</settingsSecurity>

Maven will now read our encrypted master password from the file we specified in the relocation element, on our removable drive.

Maven现在将从我们在relocation元素中指定的文件中读取加密的主密码,在我们的可移动驱动器上。

5. Encrypting Proxy Passwords

5.加密代理密码

Now we have a master password encrypted, we can encrypt our proxy password.

现在我们有一个加密的主密码,我们可以加密我们的代理密码

Let’s run the following command and enter our password, “changeme”, at the prompt:

让我们运行以下命令,并在提示符下输入我们的密码,”changeme”,

mvn --encrypt-password
Password:

Our encrypted password is displayed:

我们的加密密码被显示出来。

{U2iMf+7aJXQHRquuQq6MX+n7GOeh97zB9/4e7kkEQYs=}

Our final step is to edit the proxy section in our settings.xml file, and put in our encrypted password:

我们的最后一步是编辑settings.xml文件中的代理部分,并输入加密的密码

<proxies>
   <proxy>
        <id>BaeldungProxy_Encrypted</id>
        <host>proxy.baeldung.com</host>
        <port>80</port>
        <username>baeldung</username>
        <password>{U2iMf+7aJXQHRquuQq6MX+n7GOeh97zB9/4e7kkEQYs=}</password>
    </proxy>
</proxies>

Save this, and Maven should now be able to connect to the internet through our proxy, using our encrypted passwords.

保存这个,Maven现在应该能够通过我们的代理连接到互联网,使用我们的加密密码。

6. Using System Properties

6.使用系统属性

Although configuring Maven via the settings file is the recommended approach, we could declare our proxy configuration via Java System Properties.

虽然通过设置文件配置Maven是推荐的方法,但我们也可以通过Java系统属性声明我们的代理配置

If our operating system already has a proxy configured, we could set:

如果我们的操作系统已经配置了一个代理,我们可以设置。

-Djava.net.useSystemProxies=true

Alternatively, so that it is always enabled, if we have admin rights we can set this in our <JRE>/lib/net.properties file.

另外,如果我们有管理员权限,可以在<JRE>/lib/net.properties文件中设置,这样就可以始终启用。

However, let’s note that although Maven itself may respect this setting, not all plugins do, so we may still get failed connections using this method.

然而,我们要注意的是,虽然Maven本身可能会尊重这一设置,但并非所有的插件都会这样做,所以我们使用这种方法仍可能出现连接失败的情况。

Even when enabled, we can override it by setting our HTTP proxy’s details on the http.proxyHost system property:

即使启用了,我们也可以通过http.proxyHost系统属性上设置我们的HTTP代理的详细信息来覆盖它

-Dhttp.proxyHost=proxy.baeldung.com

Our proxy is listening on the default port 80, but if it listened on port 8080, we’d configure the http.proxyPort property:

我们的代理在默认的80端口上监听,但如果它在8080端口上监听,我们会配置http.proxyPort属性

-Dhttp.proxyPort=8080

And for our sites that don’t need the proxy:

对于我们那些不需要代理的网站

-Dhttp.nonLocalHosts="internal.baeldung.com|localhost|127.*|[::1]"

So, if our proxy is at 10.10.0.100, we can use:

因此,如果我们的代理是在10.10.0.100,我们可以使用。

mvn compile -Dhttp.proxyHost=10.10.0.100 -Dhttp.proxyPort=8080 -Dhttp.nonProxyHosts=localhost|127.0.0.1

Of course, if our proxy requires authentication, we’ll also add:

当然,如果我们的代理需要认证我们也将添加

-Dhttp.proxyUser=baeldung
-Dhttp.proxyPassword=changeme

And if we wanted some of these settings to apply to all of our Maven invocations, we can define them in the MAVEN_OPTS environment variable:

如果我们想让其中一些设置适用于所有的Maven调用,我们可以在MAVEN_OPTS环境变量中定义它们。

set MAVEN_OPTS= -Dhttp.proxyHost=10.10.0.100 -Dhttp.proxyPort=8080

Now, whenever we run ‘mvn‘ these settings will automatically be applied – until we exit.

现在,每当我们运行’mvn‘时,这些设置将被自动应用–直到我们退出。

7. Conclusion

7.结语

In this article, we configured a Maven proxy both with and without credentials and encrypted our password. We saw how to store our master password on an external drive, and also looked at configuring the proxy by using system properties.

在这篇文章中,我们配置了一个Maven代理,包括有证书和无证书,并对密码进行了加密。我们看到了如何将主密码存储在外部驱动器上,还看到了通过使用系统属性来配置代理。

Now we can share our settings.xml file with our colleagues without giving them our passwords in plain text, and show them how to encrypt theirs!

现在,我们可以与我们的同事分享我们的settings.xml文件,而不必将我们的密码以纯文本形式交给他们,并向他们展示如何加密他们的密码!

As usual, the examples in this article are available over on GitHub.

像往常一样,本文中的例子可以在GitHub上找到over