Как я могу получить сертификат клиента в Netty Handler для идентификации пользователя? - PullRequest
5 голосов
/ 20 марта 2012

Я успешно запускаю Netty с 2-сторонним SSL (см. Настройка Netty с 2-сторонним SSL Handsake (сертификат клиента и сервера) ).

Однако в некоторых моих обработчиках мне нужно знать о пользователе, который использует приложение.Я обнаружил, что не могу понять, как получить информацию, такую ​​как DN сертификата пользователя, в моих обработчиках.

Я бы подумал, что он будет доступен где-нибудь в ChannelHandlerContext, но это не так.Любые предложения?

Я знаю, что SSLEngine где-то имеет к нему доступ, но я не вижу ничего о получении доступа в публичном API SSLEngine.Я знаю, что у него есть доступ в операции рукопожатия .... но как мне его получить?

Ответы [ 3 ]

9 голосов
/ 01 июня 2013

SSLEngine можно получить через Pipline / ChannelHandlerContext

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

Это позволяет вам получить сертификаты в объектах-обработчиках. Обратите внимание, что SSL-Handshake должен быть завершен, когда вы делаете это. В противном случае вы получите

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);
    }
} 
8 голосов
/ 20 марта 2012

SSLEngine.getSession().getPeerCertificateChain(). Нулевой записью является собственный сертификат пира.

0 голосов
/ 25 июля 2018

Я использовал следующие коды для получения сертификата клиента и эмитента сертификата. Надеюсь, это поможет.

 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;
}
...