欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Tomcat8.5配置https时包 java.lang.IllegalStateException: SSL session ID not available错误的解决

程序员文章站 2024-02-28 19:47:34
...

Tomcat8.5配置https时包 java.lang.IllegalStateException: SSL session ID not available错误的解决

背景

目前开发手机App和微信小程序时调用的数据接口为了安全规范的一般都要求使用https协议访问。https = http + (TLS/SSL),比较简单的做法就是在阿里云上购买SSL证书(也可以申请免费版的,有效期是一年,对于开发测试绝对够了),然后在服务器端进行证书的配置。详情参看:https://help.aliyun.com/document_detail/98576.html?spm=5176.b62838115.0.dexternal.508c56a7Id5SQX

问题

阿里云提供的帮助手册主要是以tomcat7版本为例进行讲解的,关键配置如下:

<Connector port="443"
	    protocol="HTTP/1.1"
	    SSLEnabled="true"
	    scheme="https"
	    secure="true"
	    keystoreFile="cert/xxxx.pfx"
	    keystoreType="PKCS12"
	    keystorePass="xxxx"   
	    clientAuth="false"
	    SSLProtocol="TLSv1+TLSv1.1+TLSv1.2"
	    ciphers="TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256" />

对于tomcat8.5中关于这部分的配置有所变化,因此这种方式在tomcat8.5中使用时会不断的在tomcat日志中出现警告。查阅帮助后发现tomcat8.5的配置如下:

<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true" >
        <SSLHostConfig>
            <Certificate certificateKeystoreFile="cert/3681487_dataservice.wongoing.cn.pfx"
                         certificateKeystoreType="PKCS12"
                         certificateKeystorePassword="v30lAY2q"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>

但是这样配置完毕后还有一个SSL session ID not available警告,信息如下:

03-Nov-2020 13:46:33.042 警告 [https-openssl-nio-443-exec-3] org.apache.coyote.AbstractProcessor.populateSslRequestAttributes Exception getting SSL attributes
 java.lang.IllegalStateException: SSL session ID not available
        at org.apache.tomcat.util.net.openssl.OpenSSLEngine$OpenSSLSession.getId(OpenSSLEngine.java:1048)
        at org.apache.tomcat.util.net.jsse.JSSESupport.getSessionId(JSSESupport.java:156)
        at org.apache.coyote.AbstractProcessor.populateSslRequestAttributes(AbstractProcessor.java:605)
        at org.apache.coyote.AbstractProcessor.action(AbstractProcessor.java:358)
        at org.apache.coyote.Request.action(Request.java:393)
        at org.apache.catalina.connector.Request.getAttribute(Request.java:900)
        at org.apache.catalina.connector.Request.getAttributeNames(Request.java:982)
        at com.sun.faces.application.WebappLifecycleListener.requestDestroyed(WebappLifecycleListener.java:110)
        at com.sun.faces.config.ConfigureListener.requestDestroyed(ConfigureListener.java:346)
        at org.apache.catalina.core.StandardContext.fireRequestDestroyEvent(StandardContext.java:5946)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:182)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

解决

又经过一轮问题排查,发现这是启用TLS会话票据的副作用。如果在SSLHostConfig上设置disableSessionTickets=“true”,就会看到TLS会话id,错误也会消失。完整配置如下:

<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true" >
        <SSLHostConfig disableSessionTickets="true">
            <Certificate certificateKeystoreFile="cert/3681487_dataservice.wongoing.cn.pfx"
                         certificateKeystoreType="PKCS12"
                         certificateKeystorePassword="v30lAY2q"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>

这样就一切正常了,日志中也没有关于SSL的警告信息了。