提问人:Anthony Vinay 提问时间:11/10/2023 最后编辑:Anthony Vinay 更新时间:11/13/2023 访问量:56
在 Spring Boot 3 中验证客户端证书
Validate client certificate in Spring boot 3
问:
Java 应用程序正在使用 Spring Boot 3 和 Java 17,其中公开了一些 REST API。进行 API 调用时,仅针对特定端点,我想提取客户端证书并对其进行验证。
curl 命令调用 API :
curl -X POST "https://localhost:8443/api/auth" \
-H "accept: */*" \
-H "Content-Type: application/json" \
-H "skv_client_correlation_id: xyz" \
-d '{"xyz": "xyz"}' \
--cert client_public_certificate.crt \
--key client_private_key.key \
--cacert server_public_certificate.crt
在升级到 Spring Boot 3 之前,在 Spring Boot 2 中,客户端证书已通过以下方式进行验证:
public class CertificateFilter extends OncePerRequestFilter {
private final KeyStore keyStore;
@Override
protected void doFilterInternal(
@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull FilterChain filterChain
)
throws ServletException, IOException {
try {
X509Certificate[] certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm()
);
trustManagerFactory.init(keyStore);
for (TrustManager trustManager : trustManagerFactory.getTrustManagers()) {
if (trustManager instanceof X509TrustManager x509TrustManager) {
x509TrustManager.checkServerTrusted(certs, "RSA");
}
}
} catch (CertificateException | IllegalArgumentException e) {
log.warn("Invalid certificate: {}", e.getMessage());
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid certificate");
return;
} catch (Exception e) {
log.error("Error during certificate validation: {}", e.getMessage());
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error during certificate validation");
return;
}
filterChain.doFilter(request, response);
}
}
升级 Spring Boot 3 后,请求不包含“javax.servlet.request.X509Certificate”,也不包含“jakarta.servlet.request.X509Certificate”属性(即证书始终为 null)。我是否可以知道如何仅验证特定端点的客户端证书?
答: 暂无答案
评论
server.ssl.client-auth=need
server.ssl.*