Authentication with HttpUrlConnection – 用HttpUrlConnection进行认证

最后修改: 2019年 9月 30日

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

1. Overview

1.概述

In this tutorial, we’re going to explore how to authenticate HTTP requests using the HttpUrlConnection class.

在本教程中,我们将探讨如何使用HttpUrlConnection类对HTTP请求进行认证。

2. HTTP Authentication

2.HTTP认证

In web applications, servers may require clients to authenticate themselves. Failing to comply usually results in the server returning an HTTP 401 (Unauthorized) status code.

在网络应用中,服务器可能要求客户进行自我认证。如果不遵守,通常会导致服务器返回HTTP 401(未经授权)的状态代码。

There are multiple authentication schemes that differ in the security strength they provide. However, the implementation effort varies as well.

有多种认证方案,它们在提供的安全强度方面有所不同。然而,实施工作也各不相同。

Let’s see three of them:

让我们看看其中的三个。

  • basic is a scheme which we’ll say more about in the next section
  • digest applies hash algorithms on user credentials and a server-specified nonce
  • bearer utilizes access tokens as part of OAuth 2.0

3. Basic Authentication

3.基本认证

Basic authentication allows clients to authenticate themselves using an encoded user name and password via the Authorization header:

基本认证允许客户通过Authorization头使用编码的用户名和密码进行自我认证。

GET / HTTP/1.1
Authorization: Basic dXNlcjpwYXNzd29yZA==

To create the encoded user name and password string, we simply Base64-encode the username, followed by a colon, followed by the password:

为了创建编码后的用户名和密码字符串,我们只需对用户名进行Base64编码,然后是冒号,接着是密码。

basic(user, pass) = base64-encode(user + ":" + pass)

Remember some caution from RFC 7617, though:

不过,请记住RFC 7617中的一些谨慎意见。

This scheme is not considered to be a secure method of user authentication unless used in conjunction with some external secure system such as TLS

这种方案不被认为是一种安全的用户认证方法,除非与一些外部安全系统(如TLS)结合使用。

This is, of course, since the user name and password travel as plain text over the network within each request.

当然,这是因为用户名和密码在每个请求中都是以纯文本形式在网络上传播。

4. Authenticate a Connection

4.验证一个连接

Okay, with that as background, let’s jump into configuring HttpUrlConnection to use HTTP Basic.

好了,有了这个背景,让我们开始配置HttpUrlConnection以使用HTTP Basic。

The class HttpUrlConnection can send requests, but first, we have to obtain an instance of it from an URL object:

HttpUrlConnection可以发送请求,但首先,我们必须从一个URL对象中获得它的实例。

HttpURLConnection connection = (HttpURLConnection) url.openConnection();

A connection offers many methods to configure it, like setRequestMethod and setRequestProperty.

一个连接提供了许多方法来配置它,如setRequestMethodsetRequestProperty。

As odd as setRequestProperty sounds, this is the one we want.

尽管setRequestProperty听起来很奇怪,但这是我们想要的。

Once we’ve joined the user name and password using “:”, we can use the java.util.Base64 class to encode the credentials:

一旦我们使用”: “连接了用户名和密码,我们就可以使用java.util.Base64类来编码证书。

String auth = user + ":" + password;
byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.UTF_8));

Then, we create the header value from the literal “Basic ” followed by the encoded credentials:

然后,我们从字面意思 “Basic “和编码后的证书中创建标题值。

String authHeaderValue = "Basic " + new String(encodedAuth);

Next, we call the method setRequestProperty(key, value) to authenticate the request. As mentioned previously, we have to use “Authorization” as our header and “Basic ” + encoded credentials as our value:

接下来,我们调用方法setRequestProperty(key, value)来验证请求。如前所述,我们必须使用“Authorization”作为我们的头,“Basic ” + encoded credentials作为我们的值:

connection.setRequestProperty("Authorization", authHeaderValue);

Finally, we need to actually send the HTTP request, like for example by calling getResponseCode(). As a result, we get an HTTP response code from the server:

最后,我们需要实际发送HTTP请求,比如说通过调用getResponseCode()。结果是,我们从服务器上得到一个HTTP响应代码。

int responseCode = connection.getResponseCode();

Anything in the 2xx family means that our request including the authentication part was okay!

2xx系列中的任何东西都意味着我们的请求包括认证部分都是好的!

5. Java Authenticator

5.Java认证器

The above-mentioned basic auth implementation requires setting the authorization header for every request. In contrast, the abstract class java.net.Authenticator allows setting the authentication globally for all connections.

上面提到的基本auth实现需要为每个请求设置授权头。相比之下,抽象类java.net.Authenticator允许为所有连接设置全局认证

We need to extend the class first. Then, we call the static method Authenticator.setDefault() in order to register an instance of our authenticator:

我们首先需要扩展这个类。然后,我们调用静态方法Authenticator.setDefault() ,以便注册我们的认证器的实例。

Authenticator.setDefault(new BasicAuthenticator());

Our basic auth class just overrides the getPasswordAuthentication() non-abstract method of the base class:

我们的基本 auth 类只是覆盖了基类的 getPasswordAuthentication() 非抽象方法。

private final class BasicAuthenticator extends Authenticator {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, password.toCharArray());
}
}

The Authenticator class utilizes the credentials of our authenticator to fulfill the authentication scheme required by the server automatically.

认证器类利用我们的认证器的凭证来自动完成服务器所要求的认证方案。

6. Conclusion

6.结论

In this short tutorial, we’ve seen how to apply basic authentication to requests sent via HttpUrlConnection.

在这个简短的教程中,我们已经看到如何将基本认证应用于通过HttpUrlConnection发送的请求。

As always, the code example can be found on GitHub.

一如既往,代码示例可以在GitHub上找到