在 Quarkus REST 用戶端中使用 @ClientBasicAuth
1. 概述
Quarkus 是一個基於 Java 的框架,用於建立基於 Jakarta EE 和 MicroProfile 的應用程序,主要圍繞 REST 服務。為了使存取這些更容易,Quarkus 提供了一個REST 用戶端,允許我們使用類型安全的代理物件存取此類 REST 服務。
當REST資源受到保護時,我們需要對自己進行身份驗證。在 REST/HTTP 中,這通常是透過發送包含我們的憑證的 HTTP 標頭來完成的。不幸的是,REST 用戶端 API 不包含任何提供安全性詳細資訊的方法,甚至不包含帶有請求的 HTTP 標頭。
在本教程中,我們將了解如何透過 Quarkus (MicroProfile) REST 用戶端存取受保護的 REST 服務。 Quarkus 提供了一種簡單的方法來提供基本驗證的憑證: @ClientBasicAuth
註解.
2. 設定受保護的服務
讓我們先使用 Quarkus 設定受保護的服務。
讓我們考慮以下 REST 服務介面:
@Path("/hello")
@RequestScoped
public interface MyService {
@GET
@Produces(TEXT_PLAIN)
String hello();
}
然後,我們來實作MyService:
public class MyServiceImpl implements MyService {
@Override
@RolesAllowed("admin")
public String hello() {
return "Hello from Quarkus REST";
}
}
@RolesAllowed
註解位於實作類別上,而不是位於介面上。令人驚訝的是,這是必要的,因為@RolesAllowed
註解不是從介面繼承的。但是,這可能還不錯,因為角色名稱可以被視為不應該公開的內部細節。
預設情況下,當我們啟用安全性時,Quarkus 會啟動基本身份驗證機制。但是,我們必須提供一個身分儲存(Quarkus 中的IdentityProvider
)。基本上,我們可以透過在類別路徑上提供它來做到這一點。在本例中,我們將透過將以下內容放入pom.xml
來使用基於簡單屬性檔案的身份儲存:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-elytron-security-properties-file</artifactId>
</dependency>
這會啟動安全性(透過其傳遞依賴io.quarkus:quarkus-elytron-security
)並將上述身分儲存放在類別路徑上。我們可以使用application.properties
中的屬性將使用者及其密碼和角色新增至此儲存體:
quarkus.http.auth.basic=true
quarkus.security.users.embedded.enabled=true
quarkus.security.users.embedded.plain-text=true
quarkus.security.users.embedded.users.john=secret1
quarkus.security.users.embedded.roles.john=admin,user
RestClientBuilder
和@ClientBasicAuth
讓我們看看如何使用RestClientBuilder
呼叫受保護的服務。
這是一個類型安全的調用,不使用憑證:
MyService myService = RestClientBuilder.newBuilder()
.baseUri(URI.create("http://localhost:8081"))
.build(MyService.class);
myService.hello();
這將為 REST 服務建立一個代理,然後我們可以像呼叫本地類別一樣呼叫該代理。
提供安全憑證的一種方法是使用@ClientHeaderParam
註解原始 Jakarta REST 介面。另一種方法是從這個原始介面擴展並將註釋放在那裡。在這兩種情況下,我們都必須使用註解指定的回呼方法手動(透過程式碼)產生正確的標頭。由於我們使用基本身份驗證,因此我們可以利用@ClientBasicAuth
註釋。
為了使用@ClientBasicAuth
提供基本驗證的使用者名稱/密碼憑證,我們建立一個特定於給定使用者的新介面類型。因此,使用者名稱和密碼不存在動態方面。以這種方式創建的每個類型都對應到一個特定的使用者。當應用程式使用一個或多個靜態定義的系統使用者存取遠端服務時,這非常有用。
讓我們建立介面類型:
@ClientBasicAuth(username = "john", password = "secret1")
public interface MyServiceJohnRightCredentials extends MyService {
}
隨後,我們傳入帶有憑證的類型而不是原始類型:
MyService myService = RestClientBuilder.newBuilder()
.baseUri(URI.create("http://localhost:8081"))
.build(MyServiceJohnRightCredentials.class);
myService.hello();
使用上面的程式碼,Quarkus RestClientBuilder
產生正確的標頭,以使用基本驗證存取 REST 服務。值得注意的是,為了簡單起見,我們在這裡使用常數。在實踐中,我們可以使用像${john.password}
這樣的表達式來引用配置屬性。
4. 結論
在本文中,我們了解如何設定受基本驗證保護的 REST 服務,以及如何使用@ClientBasicAuthentication
註釋隨後存取此類服務。
我們看到,使用這個ClientBasicAuthentication
註釋,我們不必修改現有的 REST 介面。然而,我們也觀察到我們以這種方式設定靜態(預定義)使用者; @ClientBasicAuthentication
不適合動態輸入。
與往常一樣,本文中使用的所有程式碼範例都可以 在 GitHub 上找到。