我有一个进行TLS重新协商的100%https网络服务器。这非常有用,以便用户可以在单击登录按钮并要求其提供客户证书之前,先访问该网站并获得一些漂亮的页面。以下是进行重新协商line 213-236 of X509Cert class的代码部分

import org.jboss.netty.handler.ssl.SslHandler

val sslh = r.underlying.context.getPipeline.get(classOf[SslHandler])

trySome(sslh.getEngine.getSession.getPeerCertificates.toIndexedSeq) orElse {
  if (!fetch) None
  else {
    sslh.setEnableRenegotiation(true) // todo: does this have to be done on every request?
    r match {
      case UserAgent(agent) if needAuth(agent) => sslh.getEngine.setNeedClientAuth(true)
      case _ => sslh.getEngine.setWantClientAuth(true)
    }
    val future = sslh.handshake()
    future.await(30000) //that's certainly way too long.
    if (future.isDone && future.isSuccess)
      trySome(sslh.getEngine.getSession.getPeerCertificates.toIndexedSeq)
    else
      None
  }
}


现在,我期望一旦有人通过X509客户端证书进行身份验证,该会话将持续一会儿并记住该证书链-例如10分钟或更长时间,无论如何至少是1分钟。实际上,这就是为什么我可以选择将变量“ fetch”设置为false来调用上述方法的原因。我希望如果有人进行了身份验证,则无需重新协商连接。

但是我注意到,在大多数浏览器中,如果要获取会话并返回X509证书,则每次都需要调用sslh.handshake()。如果“ fetch”设置为false,那么我通常会返回无。

这是正常现象,还是我做错了什么?

PS。


上面的代码是WebID protocol实现的一部分
这是使用netty 3.2.5Final。我也尝试了3.2.7Final而没有更多的运气。
因此,我不得不更改current service running the above code的代码,以使其始终强制进行握手(请参见the commit),但这并没有为我提供希望的灵活性。

最佳答案

事实证明,我对未经过滤的净值使用存在疑问。我在Play 2.0上实现相同功能时发现了这一点。

请参见bug report 215 on Play2.0,以及未过滤的bug 111: secure netty creates new TLS contexts on each connection

09-11 20:00