1. 概述
在本教程中,我們將分析如何使用 REST Assured 進行身份驗證,以正確地測試和驗證受保護的 API。
該工具支持多種身份驗證方案:
- 基本身份驗證
- 摘要身份驗證
- 表單身份驗證
- OAuth 1 和 OAuth 2
並且我們將看到每個方案的示例。
2. 使用基本身份驗證
基本身份驗證方案需要消費者發送用户 ID 和密碼,這些密碼已用 Base64 進行編碼。
REST Assured 提供了一種便捷的方式來配置請求所需的憑據:
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. 預先身份驗證
正如我們在 Spring Security 身份驗證之前的帖子中所見,服務器可能會使用 挑戰-響應機制,明確指示消費者需要驗證以訪問資源。
默認情況下,REST Assured 在發送憑據之前等待服務器發出挑戰。
這在某些情況下可能令人困擾,例如,服務器配置為檢索登錄表單而不是挑戰-響應機制。
因此,該庫提供了 preemptive 指令,我們可以使用它:
given().auth()
.preemptive()
.basic("user1", "user1Pass")
.when()
// ...
有了它,REST Assured 將在不等待 Unauthorized 響應的情況下發送憑據。
我們幾乎從不感興趣的是測試服務器的驗證能力。因此,我們通常可以添加此命令以避免複雜性和額外請求的開銷。
3. 使用 Digest 身份驗證
儘管這種方法也被認為是“弱”身份驗證方法,但使用 Digest 身份驗證在基本協議中具有優勢。
這是因為該方案避免在清晰文本中發送密碼。
儘管存在這種差異,使用 REST Assured 實現這種身份驗證形式與我們在上一部分中遵循的非常相似:
given().auth()
.digest("user1", "user1Pass")
.when()
// ...
請注意,目前該庫僅支持針對此方案的“挑戰式”身份驗證,因此我們無法像之前那樣使用preemptive()。
4. 使用表單身份驗證
許多服務提供 HTML 表單,供用户通過填寫字段和憑據進行身份驗證。
當用户提交表單時,瀏覽器會執行包含信息的 POST 請求。
通常,表單指示其將調用哪個端點,通過 action 屬性,並且每個 input 字段都對應於請求中發送的表單參數。
如果登錄表單足夠簡單並且遵循這些規則,那麼我們就可以依賴 REST Assured 來自動確定這些值:
given().auth()
.form("user1", "user1Pass")
.when()
// ...
這並不是一種最佳方法,無論如何,因為 REST Assured 需要執行額外的請求並解析 HTML 響應以查找字段。
我們還需要記住,該過程仍然可能失敗,例如,如果網頁很複雜,或者服務配置了不在 action 屬性中包含的上下文路徑。
因此,更好的解決方案是自己提供配置,明確指定三個必需字段:
given().auth()
.form(
"user1",
"user1Pass",
new FormAuthConfig("/perform_login", "username", "password"))
// ...
除了這些基本配置之外,REST Assured 包含以下功能:
- 檢測或指示網頁中的 CSRF 令牌字段
- 在請求中使用額外的表單字段
- 記錄身份驗證過程的信息
5. OAuth 支持
OAuth 實際上是一個 授權 框架,它不定義任何用於驗證用户的方法。
儘管如此,它仍然可以作為構建身份驗證和身份協議的基礎,例如 OpenID Connect。
5.1. OAuth 2.0
REST Assured 允許配置 OAuth 2.0 訪問令牌以請求受保護的資源:
given().auth()
.oauth2(accessToken)
.when()
.// ...
該庫不提供任何幫助來獲取訪問令牌,因此我們必須自己找出如何做到這一點。
對於客户端憑據和密碼流程,這很簡單,因為令牌是通過簡單地呈現相應的憑據獲得的。
另一方面,自動化授權碼流程可能並不容易,我們可能需要其他工具的幫助。
為了正確理解這個流程以及獲取訪問令牌所需的內容,我們可以查看有關該主題的這篇優秀文章。
5.2. OAuth 1.0a
在 OAuth 1.0a 的情況下,REST Assured 提供了接收消費者密鑰、密鑰、訪問令牌和令牌密鑰的方法以訪問受保護的資源:
given().accept(ContentType.JSON)
.auth()
.oauth(consumerKey, consumerSecret, accessToken, tokenSecret)
// ...
該協議需要用户輸入,因此獲得最後兩個字段將不會是一項簡單的任務。
請注意,如果使用 OAuth 2.0 功能並且版本低於 2.5.0,或者如果使用 OAuth 1.0a 功能,則需要添加 scribejava-apis 依賴項。
6. 結論
在本教程中,我們學習瞭如何使用 REST Assured 認證以訪問受保護的 API。
該庫簡化了幾乎任何方案的認證過程。