我如何 get/inject Jersey 服务器中的当前 SSLSession?

How do I get/inject the current SSLSession in Jersey server?

我有一个 JAX-RS 应用程序 (Jersey 2.22),我需要在其中获取对等 SSL 客户端证书(服务器启用了相互 SSL 身份验证)。

我想要实现的是:

@GET
@Produces(MediaType.TEXT_PLAIN)
public String clientCertificates() {
    SSLContext sslContext = SSLContext.getDefault();
    SSLSessionContext clientContext = sslContext.getClientSessionContext();
    byte[] sessionId = clientContext.getIds().nextElement();
    SSLSession clientSession = clientContext.getSession(sessionId);
    Certificate[] certificates = clientSession.getPeerCertificates();
    return "The client provided " + certificates.length + " certificates.";
}

但这会在 clientContext.getIds().nextElement() 处抛出 NoSuchElementException,即使客户端 DID 提供了服务器接受的有效 SSL 证书以建立会话(我正在使用 Glassfish 4 进行尝试, WildFly 9 和 WildFly 10)。

注意:web.xml CLIENT-CERT 身份验证方法不是我所需要的:我需要获得对客户端证书的引用。

我发现这个(未经检查的)方法可以从 ContainerRequestContext 中获取 ContainerRequestFilter 中提供的证书,如果有的话:

@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        X509Certificate[] certificates = (X509Certificate[]) requestContext.getProperty("javax.servlet.request.X509Certificate");
        Principal principal = certificates[0].getSubjectX500Principal();
    }

}