如何在Netty Handler中获取客户端证书以识别用户?

时间:2012-03-19 21:00:35

标签: ssl certificate netty

我使用双向SSL成功运行Netty(请参阅Set up Netty with 2-way SSL Handsake (client and server certificate))。

但是,在我的一些处理程序中,我需要知道正在使用该应用程序的用户。我发现我无法弄清楚如何在我的处理程序中获取用户证书DN等信息。

我认为它可以在某个地方的ChannelHandlerContext中使用,但事实并非如此。有什么建议吗?

我知道SSLEngine可以在某处访问它,但我没有看到任何关于在SSLEngine公共API中获取访问权限的信息。我知道它在握手操作中具有访问权限....但我如何得到它?

3 个答案:

答案 0 :(得分:9)

可以通过Pipline / ChannelHandlerContext

获取SSLEngine
ChannelHandlerContext ctx = ...
SslHandler sslhandler = (SslHandler) ctx.channel().pipeline().get("ssl");
sslhandler.engine().getSession().getPeerCertificateChain()[0].getSubjectDN());

这允许您获取处理程序对象中的证书。请注意,执行此操作时需要完成SSL握手。否则你会得到一个

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

异常。为了避免这种情况,你可以在处理程序中监听userEvent(在我们的例子中是HandshakeCompletionEvent),它可能看起来如下:

@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
    logger.info("userEventTriggered: {0}, Class: {1}", evt.toString(), evt.getClass());

    if (evt instanceof HandshakeCompletionEvent) {
        fetchCertificate(ctx);
    }
} 

答案 1 :(得分:8)

SSLEngine.getSession().getPeerCertificateChain()。第0个条目是对等方自己的证书。

答案 2 :(得分:0)

我使用以下代码获取客户端证书和证书的颁发者。希望对您有所帮助。

 SslHandler sslHandler = (SslHandler) ctx.channel().pipeline().get("ssl");

 X509Certificate issuer = convert(sslHandler.engine().getSession().getPeerCertificateChain()[sslHandler.engine().getSession().getPeerCertificateChain().length -1]);

 System.out.println("issuer: " + issuer);


  public static java.security.cert.X509Certificate convert(javax.security.cert.X509Certificate cert) {
    try {
        byte[] encoded = cert.getEncoded();
        ByteArrayInputStream bis = new ByteArrayInputStream(encoded);
        java.security.cert.CertificateFactory cf
                = java.security.cert.CertificateFactory.getInstance("X.509");
        return (java.security.cert.X509Certificate)cf.generateCertificate(bis);
    } catch (java.security.cert.CertificateEncodingException e) {
    } catch (javax.security.cert.CertificateEncodingException e) {
    } catch (java.security.cert.CertificateException e) {
    }
    return null;
}