Java 尽管将“disableCNCheck”设置为 true,但 https URL 主机名与通用名称 (CN) 不匹配
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21120264/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
https URL hostname not matching Common Name (CN) despite setting 'disableCNCheck' to true
提问by Withheld
I managed to configure my CXF-based client properly so that it finds the correct SSL certificate for the server on which I am running a web service:
我设法正确配置了基于 CXF 的客户端,以便它为我运行 Web 服务的服务器找到正确的 SSL 证书:
<http:conduit name="https://myserver/myws/register/soap?wsdl:{http://glob.reg.com/myws}.http-conduit">
<http:tlsClientParameters>
<sec:keyManagers keyPassword="changeit">
<sec:keyStore type="JKS" password="changeit"
file="C:\Program Files (x86)\Java\jdk1.6.0_45\jre\lib\security\cacerts"/>
</sec:keyManagers>
<sec:trustManagers>
<sec:keyStore type="JKS" password="changeit"
file="C:\Program Files (x86)\Java\jdk1.6.0_45\jre\lib\security\cacerts"/>
</sec:trustManagers>
<sec:cipherSuitesFilter>
<!-- these filters ensure that a ciphersuite with
export-suitable or null encryption is used,
but exclude anonymous Diffie-Hellman key change as
this is vulnerable to man-in-the-middle attacks -->
<sec:include>.*_EXPORT_.*</sec:include>
<sec:include>.*_EXPORT1024_.*</sec:include>
<sec:include>.*_WITH_DES_.*</sec:include>
<sec:include>.*_WITH_AES_.*</sec:include>
<sec:include>.*_WITH_NULL_.*</sec:include>
<sec:exclude>.*_DH_anon_.*</sec:exclude>
</sec:cipherSuitesFilter>
</http:tlsClientParameters>
<http:authorization>
<sec:UserName>Betty</sec:UserName>
<sec:Password>password</sec:Password>
</http:authorization>
<http:client AutoRedirect="true" Connection="Keep-Alive"/>
</http:conduit>
But... because the certificate is for a subdomain name that's different than my server's machine (maps to the same IP address), I am getting the following error:
但是...因为证书用于与我的服务器机器不同的子域名(映射到相同的 IP 地址),我收到以下错误:
Caused by: java.io.IOException: The https URL hostname does not match the Common Name (CN) on the server certificate in the client's truststore. Make sure serv
er certificate is correct, or to disable this check (NOT recommended for production) set the CXF client TLS configuration property "disableCNCheck" to true.
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1234)
at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.onFirstWrite(URLConnectionHTTPConduit.java:183)
at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47)
at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:69)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1293)
... 18 more
So...since this is a development/test system, I did just as the message proposed (set the CXF client TLS configuration property "disableCNCheck" to true):
所以...由于这是一个开发/测试系统,我按照建议的消息做了(将 CXF 客户端 TLS 配置属性“disableCNCheck”设置为 true):
<http:tlsClientParameters disableCNCheck="true">
Plus, I added the following code to my client's main class (per the suggestion in this thread):
另外,我在客户端的主类中添加了以下代码(根据此线程中的建议):
static {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
{
@Override
public boolean verify(String hostname, SSLSession session)
{
return true;
}
});
}
But...I am still getting the same error:
但是......我仍然遇到同样的错误:
Caused by: java.io.IOException: The https URL hostname does not match the Common Name (CN) on the server certificate in the client's truststore. Make sure serv
er certificate is correct, or to disable this check (NOT recommended for production) set the CXF client TLS configuration property "disableCNCheck" to true.
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1234)
at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.onFirstWrite(URLConnectionHTTPConduit.java:183)
at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47)
at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:69)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1293)
... 18 more
Any idea why?
知道为什么吗?
I mean, one of the above workarounds should have been enough to let the client ignore the certificate URL mismatch but, in my case, neither works nor the combination thereof.
我的意思是,上述解决方法之一应该足以让客户端忽略证书 URL 不匹配,但在我的情况下,既不起作用,也不起作用。
Why?
为什么?
采纳答案by David J. Liszewski
I have used CXF in several instances where
我在几个实例中使用了 CXF,其中
<http:tlsClientParameters disableCNCheck="true">
was sufficient to disable CN check.
足以禁用 CN 检查。
Are you certain your client is using that conduit configuration? My understanding is the conduit name pattern needs to match the endpoint URI in some fashion.
您确定您的客户正在使用该管道配置吗?我的理解是管道名称模式需要以某种方式匹配端点 URI。
Try setting the conduit name as follows such that any endpoint will match and see if that changes anything:
尝试按如下方式设置管道名称,以便任何端点都匹配并查看是否有任何更改:
<http:conduit name="*.http-conduit">
Update 2 Jan 2015
2015 年 1 月 2 日更新
It turns out the http-conduit
configuration name matching has two pattern formats. One involves the service's namespace and port name. The other supported format is a regular expression matched against URL endpoint specified in WSDL used to create client.
事实证明,http-conduit
配置名称匹配有两种模式格式。一种涉及服务的命名空间和端口名称。另一种支持的格式是与用于创建客户端的 WSDL 中指定的 URL 端点匹配的正则表达式。
Quoting Apache CXF User Guideregarding the http-conduit
element:
引用有关该元素的Apache CXF 用户指南http-conduit
:
The name includes the service's namespace, the WSDL port name (as found in the wsdl:service section of the WSDL), and ".http-conduit". It follows this template:
{WSDL Namespace}portName.http-conduit
Note: it's the PORT name, not the service name.
..
Another option for the name attribute is a reg-ex expression (e.g., "http://myserver.example.com:*") for the ORIGINAL URL of the endpoint. The configuration is matched at conduit creation so the address used in the WSDL or used for the JAX-WS Service.create(...) call can be used for the name.
该名称包括服务的名称空间、WSDL 端口名称(可在 WSDL 的 wsdl:service 部分找到)和“.http-conduit”。它遵循这个模板:
{WSDL Namespace}portName.http-conduit
注意:它是端口名称,而不是服务名称。
..
name 属性的另一个选项是端点的原始 URL 的reg-ex 表达式(例如,“ http://myserver.example.com:*”)。配置在管道创建时匹配,因此 WSDL 中使用的地址或用于 JAX-WS Service.create(...) 调用的地址可用于名称。
回答by Aliti
Put -Djsse.enableSNIExtension=false
in your appserver VM Options.
把-Djsse.enableSNIExtension=false
你的应用程序服务器VM选项。
回答by Palla
Add below code to set disableCNCheck
添加以下代码以设置 disableCNCheck
HTTPConduit httpConduit=(HTTPConduit)ClientProxy.getClient(port).getConduit();
TLSClientParameters tlsCP = new TLSClientParameters();
tlsCP.setDisableCNCheck(true);
httpConduit.setTlsClientParameters(tlsCP);
Use this code only in the lower environments, In higher environments, it's not recommended.
此代码仅在较低的环境中使用,在较高的环境中,不建议使用。