1.5. RESTEasy Classic 的令牌传播


quarkus-resteasy-client-oidc-token-propagation 扩展提供了两个 Jakarta REST jakarta.ws.rs.client.ClientRequestFilter 类实现,以简化身份验证信息的传播。io.quarkus.oidc.token.propagation.AccessTokenRequestFilter 传播在当前活动请求中的 Bearer 令牌,或从 Authorization 代码流机制获取的令牌,作为 HTTP Authorization 标头的 Bearer 方案值。io.quarkus.oidc.token.propagation.JsonWebTokenRequestFilter 提供相同的功能,但也提供对 JWT 令牌的支持。

当您需要传播当前的授权代码流访问令牌时,直接令牌传播将正常工作,因为代码流访问令牌(而不是 ID 令牌)旨在为当前的 Quarkus 端点传播,以代表当前经过身份验证的用户访问远程服务。

但是,应避免直接端到端的 Bearer 令牌传播。例如,Client Service A Service B,其中 Service B 接收由 Client 发送到 Service A 的令牌。在这种情况下,Service B 无法区分令牌是否来自 Service A 或直接与 客户端。对于 Service B 验证令牌来自 Service A,它应该能够断言新的签发者和受众声明。

此外,复杂的应用可能需要在传播令牌之前交换或更新令牌。例如,当 Service A 访问 Service B 时,访问上下文可能会有所不同。在这种情况下,服务 A 可能会被授予一个范围范围,或者完全不同的范围来访问服务 B

以下小节演示了 AccessTokenRequestFilterJsonWebTokenRequestFilter 可以如何提供帮助。

1.5.1. RESTClient AccessTokenRequestFilter

AccessTokenRequestFilter 将所有令牌视为 Strings,因此它可以使用 JWT 和 opaque 令牌。

您可以使用 io.quarkus.oidc.token.propagation.common.AccessTokenorg.eclipse.microprofile.rest.client.annotation.RegisterProvider 来选择性地注册 AccessTokenRequestFilter,例如:

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import io.quarkus.oidc.token.propagation.common.AccessToken;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

@RegisterRestClient
@AccessToken
@Path("/")
public interface ProtectedResourceService {

    @GET
    String getUserName();
}
Copy to clipboard

或者

import org.eclipse.microprofile.rest.client.annotation.RegisterProvider;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import io.quarkus.oidc.token.propagation.AccessTokenRequestFilter;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

@RegisterRestClient
@RegisterProvider(AccessTokenRequestFilter.class)
@Path("/")
public interface ProtectedResourceService {

    @GET
    String getUserName();
}
Copy to clipboard

另外,如果 quarkus.resteasy-client-oidc-token-propagation.register-filter 属性设置为 true,并且 quarkus.resteasy-client-oidc-token-propagation.json-web-token 属性设置为 false,则 AccessTokenRequestFilter 属性会自动注册到所有 MP Rest 或 Jakarta REST 客户端。

1.5.1.1. 在传播前交换令牌

如果需要在传播前交换当前的访问令牌,并使用 Keycloak 或其他支持 Token Exchange 令牌授权的 OpenID Connect 供应商,您可以配置 AccessTokenRequestFilter,如下所示:

quarkus.oidc-client.auth-server-url=http://localhost:8180/auth/realms/quarkus
quarkus.oidc-client.client-id=quarkus-app
quarkus.oidc-client.credentials.secret=secret
quarkus.oidc-client.grant.type=exchange
quarkus.oidc-client.grant-options.exchange.audience=quarkus-app-exchange

quarkus.resteasy-client-oidc-token-propagation.exchange-token=true
Copy to clipboard

如果您使用需要使用 JWT bearer 令牌 授权的 Azure 等提供程序来交换当前令牌,您可以配置 AccessTokenRequestFilter 以交换令牌,如下所示:

quarkus.oidc-client.auth-server-url=${azure.provider.url}
quarkus.oidc-client.client-id=quarkus-app
quarkus.oidc-client.credentials.secret=secret

quarkus.oidc-client.grant.type=jwt
quarkus.oidc-client.grant-options.jwt.requested_token_use=on_behalf_of
quarkus.oidc-client.scopes=https://graph.microsoft.com/user.read,offline_access

quarkus.resteasy-client-oidc-token-propagation.exchange-token=true
Copy to clipboard
注意

AccessTokenRequestFilter 将使用 OidcClient 来交换当前令牌,您可以使用 quarkus.oidc-client.grant-options.exchange 设置 OpenID Connect 提供程序期望的额外交换属性。

AccessTokenRequestFilter 默认使用 OidcClient。可以使用 quarkus.resteasy-client-oidc-token-propagation.client-name 配置属性来选择命名的 OidcClient

1.5.2. RestClient JsonWebTokenRequestFilter

如果使用 Bearer JWT 令牌,则建议使用 JsonWebTokenRequestFilter,其中这些令牌可以具有其声明,如 签发者使用者 修改,以及再次修改更新的令牌(如重新签名)。它需要一个注入的 org.eclipse.microprofile.jwt.JsonWebToken,因此无法使用不透明令牌。另外,如果您的 OpenID Connect Provider 支持 Token Exchange 协议,则建议使用 AccessTokenRequestFilter,因为 JWT 和不透明 bearer 令牌都可以安全地与 AccessTokenRequestFilter 交换。

JsonWebTokenRequestFilter 可使 Service A 实施轻松更新注入的 org.eclipse.microprofile.jwt.WebToken 及新的 签发者audience 声明值,并使用新的签名再次保护更新的令牌。唯一的困难是确保服务 A 具有从安全文件系统或远程安全存储(如 Vault)置备的签名密钥。

您可以使用 io.quarkus.oidc.token.propagation.JsonWebTokenorg.eclipse.microprofile.rest.client.annotation.RegisterProvider 来选择性地注册 JsonWebTokenRequestFilter,例如:

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import io.quarkus.oidc.token.propagation.JsonWebToken;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

@RegisterRestClient
@JsonWebToken
@Path("/")
public interface ProtectedResourceService {

    @GET
    String getUserName();
}
Copy to clipboard

或者

import org.eclipse.microprofile.rest.client.annotation.RegisterProvider;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import io.quarkus.oidc.token.propagation.JsonWebTokenRequestFilter;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

@RegisterRestClient
@RegisterProvider(JsonWebTokenRequestFilter.class)
@Path("/")
public interface ProtectedResourceService {

    @GET
    String getUserName();
}
Copy to clipboard

另外,如果 quarkus.resteasy-client-oidc-token-propagation.register-filter 和 quarkus.resteasy-client-oidgation.register-filter 和 quarkus.resteasy-client-oidc-token-propagation.json-web-token 属性都会自动注册 JsonWebTokenRequestFilter

1.5.2.1. 在传播前更新令牌

如果注入的令牌需要有其 iss (issuer)或 aud (audience)声明使用新签名再次更新和保护,则可以配置 JsonWebTokenRequestFilter,如下所示:

quarkus.resteasy-client-oidc-token-propagation.secure-json-web-token=true
smallrye.jwt.sign.key.location=/privateKey.pem
# Set a new issuer
smallrye.jwt.new-token.issuer=http://frontend-resource
# Set a new audience
smallrye.jwt.new-token.audience=http://downstream-resource
# Override the existing token issuer and audience claims if they are already set
smallrye.jwt.new-token.override-matching-claims=true
Copy to clipboard

如前文所述,如果使用 Keycloak 或支持 Token Exchange 协议的 OpenID Connect Provider,请使用 AccessTokenRequestFilter

1.5.3. 测试

通常,您必须准备两个 REST 测试端点。第一个端点使用带有注册的令牌传播过滤器注入的 MP REST 客户端来调用第二个端点。

要了解它如何实现,请特别遵循 OpenID Connect 客户端和令牌传播 快速入门及其 测试 部分。

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat, Inc.