Nginx配置引起的SSL证书认证失败

本文详细介绍了在Nginx部署中遇到的SSL证书认证失败问题,问题源于Java客户端不支持SNI协议,导致Nginx无法正确获取客户端证书。通过Wireshark协议分析和对SSL握手过程的研究,最终发现需要配置default server来解决这个问题,同时提醒在产品上线前应充分测试,避免类似兼容性问题。
摘要由CSDN通过智能技术生成

1. 背景

目前公司对外开放了一个云服务平台,提供一些功能供商户接入使用。整个项目的架构是基于Spring + MyBatis的。另外,商户端的服务接口是基于SOAP WebService的,这部分使用CXF实现。
安全方面采用了Spring Security,可以对商户提供证书认证或密码认证。但是出于安全考虑,目前只开放了证书认证。为了使用证书认证商户,我们创建了一个自签名的CA,用来生成商户使用的客户端证书。在验证上,使用Nginx验证客户端证书是否是指定CA产生的。另外,为了防止被作废的证书(例如给商户颁发了新证书后,原证书应该作废,但是原证书也是由指定CA产生的)再次使用,在代码层面对证书进行了进一步的验证(这一点是通过Nginx将客户端证书作为Header传递到Java后台实现的,有时间以后再讲)。

1.1. 部署架构

云服务平台部署在aliyun上,大致上结构是这样的(只涉及到了网络访问层面的东西):

商户 -https-> aliyun负载均衡 -tcp转发-> Nginx -http-> Jetty --> ClientCertificateFromProxyFilter

商户访问云服务的时候,需要使用我们提供的客户端证书来建立https链接。aliyun的LB只负责TCP转发,不对协议进行分析。因此从aliyun到Nginx之间实际的数据流是https数据流。Nginx接受到请求后,验证客户端证书是否正确,并将客户端证书设置为HTTP请求中的Header变量,然后请求后台的Jetty服务器。
我们代码中实现了一个Filter(ClientCertificateFromProxyFilter),它的唯一作用是检查过来的HTTP请求中有没有变量SSL_CLIENT_CERT,如果有则把它转换成一个Certificate对象,添加到HTTP请求中,从而将一个HTTP请求模拟成一个HTTPS请求,这样Spring Security就能够进行证书认证了。

3. 问题

在上线之前,按照以往的经验,我们测试了通过浏览器访问受保护的资源来测试HTTPS是否工作正常。因为提前在浏览器中导入了客户端证书,因此浏览器上能够弹出对话框选择客户端证书,选择之后就能够访问指定的资源了。

我们推荐商户使用CXF作为接入方式,一般的代码如下:

<jaxws:client id="uidService"
    serviceClass="com.xwf.cloudauth...."
    address="https://.../api/UidApiService">
</jaxws:client>
<http-conf:conduit name="*.http-conduit">
    <http-conf
  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值