You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus如何从X-ARR-ClientCert请求头获取客户端证书完成身份认证

有成熟可行的实现方案,不需要从零搭建完整的认证逻辑,仅需基于Quarkus现有安全扩展做少量自定义开发即可满足需求。

核心实现逻辑

你不需要完全重写安全校验全链路,仅需实现自定义请求认证机制,配合Quarkus自带的TrustStore能力和身份提供器即可完成校验,具体步骤如下:

1. 前置Azure配置校验

首先确认Azure App Service侧配置符合要求:

  • 将App Service的客户端证书模式设置为Required或Optional,确保负载均衡器会把客户端证书编码后写入X-ARR-ClientCert请求头
  • 无需担心请求头伪造风险:Azure App Service默认不会将外部请求携带的X-ARR-ClientCert头透传给应用,仅会写入负载均衡器层面接收的客户端证书内容

2. 依赖引入

在项目的构建配置中引入Quarkus安全核心扩展,以Maven为例:

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-elytron-security</artifactId>
</dependency>
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-security</artifactId>
</dependency>

3. 自定义请求认证机制

实现HttpAuthenticationMechanism接口,完成证书提取、校验逻辑,直接复用Quarkus已加载的TrustStore做校验:

@Alternative
@Priority(1)
@ApplicationScoped
public class ArrClientCertAuthMechanism implements HttpAuthenticationMechanism {

    @Inject
    TrustManagerFactory trustManagerFactory;
    @Inject
    IdentityProviderManager identityProviderManager;

    @Override
    public Uni<SecurityIdentity> authenticate(RoutingContext context, IdentityProviderManager identityProviderManager) {
        String certHeader = context.request().getHeader("X-ARR-ClientCert");
        // 无证书头直接跳过当前认证机制,由后续安全规则处理无权限请求
        if (certHeader == null || certHeader.isBlank()) {
            return Uni.createFrom().nullItem();
        }
        try {
            // 解码请求头内容生成X509证书实例
            byte[] certBytes = Base64.getDecoder().decode(certHeader.trim());
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            X509Certificate clientCert = (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(certBytes));
            
            // 复用现有TrustStore做证书信任校验
            X509TrustManager trustManager = (X509TrustManager) trustManagerFactory.getTrustManagers()[0];
            trustManager.checkClientTrusted(new X509Certificate[]{clientCert}, "RSA");
            
            // 复用Quarkus自带的X509身份提供器生成SecurityIdentity
            return identityProviderManager.authenticate(new X509AuthenticationCredential(clientCert));
        } catch (Exception e) {
            return Uni.createFrom().failure(new AuthenticationFailedException("客户端证书校验不通过", e));
        }
    }

    @Override
    public Uni<ChallengeData> getChallenge(RoutingContext context) {
        return Uni.createFrom().item(new ChallengeData(HttpResponseStatus.UNAUTHORIZED.code(), HttpHeaders.WWW_AUTHENTICATE, "ClientCertificate"));
    }

    @Override
    public Set<Class<? extends AuthenticationRequest>> getCredentialTypes() {
        return Collections.singleton(X509AuthenticationCredential.class);
    }
}

4. TrustStore配置

直接在application.properties中配置你的信任库,Quarkus会自动加载并注入到上下文,无需自行读取解析:

# TrustStore配置
quarkus.tls.trust-store.type=JKS
quarkus.tls.trust-store.path=classpath:your-truststore.jks
quarkus.tls.trust-store.password=your-truststore-password
关于自定义Identity Provider的说明
  • 如果你仅需要完成证书信任校验,默认用Quarkus自带的X509IdentityProvider即可,无需额外自定义Identity Provider
  • 如果你需要从证书的扩展字段提取自定义身份标识、绑定业务角色、对接内部权限系统,再自行实现IdentityProvider<X509AuthenticationCredential>接口,补充对应的身份映射逻辑即可
注意事项
  • 生产环境需额外校验证书的有效期、吊销状态,避免过期证书通过校验
  • 所有未携带合法证书的请求会被自动返回401状态码,也可结合Quarkus的@RolesAllowed注解实现接口粒度的权限控制

内容的提问来源于stack exchange,提问作者SlowTree

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 16:18:03