1. 概述

在本教程中,我们将学习如何在使用 REST Assured 测试和验证受保护的 API 时进行认证。

REST Assured 支持多种常见的认证方式:

  • 基础认证(Basic Authentication)
  • 摘要认证(Digest Authentication)
  • 表单认证(Form Authentication)
  • OAuth 1 和 OAuth 2

我们将通过代码示例逐一讲解这些认证方式的使用。


2. 使用基础认证(Basic Authentication)

基础认证机制 要求客户端将用户名和密码进行 Base64 编码后发送给服务器。

REST Assured 提供了非常简洁的 API 来配置基础认证信息:

given().auth()
  .basic("user1", "user1Pass")
  .when()
  .get("http://localhost:8080/spring-security-rest-basic-auth/api/foos/1")
  .then()
  .assertThat()
  .statusCode(HttpStatus.OK.value());

2.1 预认证(Preemptive Authentication)

Spring Security 基础认证教程 中我们提到过,服务器通常会使用 挑战-响应机制 来提示客户端需要认证。

默认情况下,REST Assured 会等待服务器返回 401 Unauthorized 响应后再发送认证信息。

但在某些场景下,比如服务器返回的是登录页面而不是挑战响应,这种方式就可能出问题。

为了解决这个问题,REST Assured 提供了 preemptive() 方法:

given().auth()
  .preemptive()
  .basic("user1", "user1Pass")
  .when()
  // ...

这样 REST Assured 就会在首次请求中直接带上认证信息,不再等待挑战。

✅ 实际测试中我们通常并不关心服务器是否能正确发起挑战,因此建议直接加上 preemptive(),避免多一次请求带来的开销和潜在问题。


3. 使用摘要认证(Digest Authentication)

尽管摘要认证也被认为是一种较弱的认证方式,但相比基础认证,它更安全,因为它不会以明文形式传输密码。

REST Assured 中的使用方式与基础认证非常类似:

given().auth()
  .digest("user1", "user1Pass")
  .when()
  // ...

⚠️ 注意:目前 REST Assured 对摘要认证仅支持挑战式认证,不支持使用 preemptive() 预认证方式


4. 使用表单认证(Form Authentication)

很多 Web 应用通过 HTML 表单让用户输入用户名和密码来登录。当用户提交表单时,浏览器会向指定接口发送 POST 请求。

如果登录页面足够简单,REST Assured 可以自动识别表单字段并提交认证信息:

given().auth()
  .form("user1", "user1Pass")
  .when()
  // ...

但这种方式需要 REST Assured 先发送一次请求获取 HTML 页面内容,再解析出表单字段,效率较低。

⚠️ 如果页面结构复杂或者没有提供完整的表单信息,这种方式可能会失败。

更推荐的方式是显式指定登录接口和字段名称:

given().auth()
  .form(
    "user1",
    "user1Pass",
    new FormAuthConfig("/perform_login", "username", "password"))
  // ...

此外,REST Assured 还支持:

  • 自动检测或手动指定 CSRF token 字段
  • 添加额外的表单参数
  • 输出认证过程的日志信息

5. OAuth 支持

OAuth 是一种授权框架,它本身并不定义用户认证机制,但它可以作为构建认证和身份协议的基础,比如 OpenID Connect

5.1 OAuth 2.0

REST Assured 支持使用 OAuth 2.0 的访问令牌来访问受保护的资源:

given().auth()
  .oauth2(accessToken)
  .when()
  .// ...

⚠️ 注意:REST Assured 不会帮你获取 token,你需要自己处理认证流程获取 access token。

对于 Client Credentials 和 Resource Owner Password Credentials 这两种流程,获取 token 比较简单,只需要发送客户端凭证或用户名密码即可。

但如果是 Authorization Code 流程,自动化起来就比较复杂了,可能需要借助其他工具辅助完成。可以参考这篇 OAuth 授权码流程详解

5.2 OAuth 1.0a

对于 OAuth 1.0a,REST Assured 提供了如下方式配置认证信息:

given().accept(ContentType.JSON)
  .auth()
  .oauth(consumerKey, consumerSecret, accessToken, tokenSecret)
  // ...

OAuth 1.0a 协议通常需要用户交互来完成授权流程,因此获取 access token 和 token secret 会比较麻烦。

⚠️ 如果你使用的是 REST Assured 2.5.0 之前的版本,或使用了 OAuth 1.0a 功能,需要额外添加依赖:

<dependency>
    <groupId>com.github.scribejava</groupId>
    <artifactId>scribejava-apis</artifactId>
    <version>6.9.0</version>
</dependency>

6. 小结

通过本文我们了解了 REST Assured 支持的几种常见认证方式,并通过代码示例演示了如何使用它们访问受保护的 API。

REST Assured 在认证方面的封装非常简洁,几乎涵盖了所有主流的认证方案,能极大简化我们在接口测试中的认证流程。

✅ 实际使用中,建议优先使用 preemptive() 避免不必要的请求往返;对于复杂认证流程,如 OAuth 2.0 的授权码模式,可能需要结合其他工具链来完成。

完整示例代码和使用说明可在 GitHub 仓库 获取。


原始标题:REST Assured Authentication | Baeldung

« 上一篇: Java Weekly, 第278期
» 下一篇: Google Tink 使用指南