SpringCloud Gateway不再是基于SpringMVC,而是基于webflux,采用netty运行,所以相对于之前基于springmvc的springboot配置会有一定的改变。
官方文档中对于https配置的介绍:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.1.0.RC3/single/spring-cloud-gateway.html#_tls_ssl
SpringCloud Gateway Https配置步骤:(基于springboot2.1.1版本)
- 获取证书:
我是买了腾讯云的域名,目前有活动,新用户1块钱就可以买一年的域名,老用户2块钱一年。购买域名之后进行实名认证一下就可以申请证书了。
点击链接https://console.cloud.tencent.com/ssl进入控制台,证书管理,如下图所示:
具体的情况就不详细介绍了,可以自行查看腾讯云说明。
此外,也可以通过自己生成证书,不过比较麻烦,可以自行百度证书的生成。 - 下载证书:
下载后是一个压缩包,里面有针对不同场景的证书和秘钥,压缩包目录如下图所示:
不同场景下给的证书类型是不一样的,也可以通过腾讯云给的工具转转成自己想要的类型,
转换工具地址:https://www.trustasia.com/tools/cert-converter.htm
本文采用的是IIS中的PKCS12格式的证书(文件的名字可以自己修改,默认是用的域名)
下面进行SpringCloudGateway工程的配置:
- 添加eureka client、gateway依赖
注:不能添加springboot web组件的依赖,否则会抛异常,因为gateway已经默认采用了webflux,所以不需要springmvc相关依赖。 - 将证书放到resources文件夹下,例如本博客中的xjl-keystore.pfx证书文件
- 配置文件:
server: port: 9000 ssl: enabled: true key-store-password: xxxxxxxxx # 腾讯云申请生成证书时填写的密码,如果申请时没有填写,name下载的证书文件家中会包括一个keystorePass.txt文件,里面就是密码 key-store: classpath:xjl-keystore.pfx # 我自己进行了文件重命名 key-store-type: PKCS12
踩坑:
按照上述的配置,可以通过https访问到gateway,但是gateway转发到后台微服务仍然是https请求,所以需要后台微服务也设置成https请求,并且在注册中心注册时就采用域名注册,这样是非常麻烦的。用过Zuul的都知道,Zuul会将https请求转换为http请求给后台微服务。下一篇博客介绍gateway将https请求转换为http请求。
如果,后台微服务设置为http,那么gateway会抛出如下异常:
2019-02-22 11:16:45.155 ERROR 4008 --- [ctor-http-nio-4] r.n.resources.PooledConnectionProvider : [id: 0xd143d669, L:/172.16.10.167:9587 - R:/114.116.137.241:8080] Pooled connection observed an error
io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record: 485454502f312e3120343030200d0a436f6e74656e742d547970653a20746578742f68746d6c3b636861727365743d7574662d380d0a436f6e74656e742d4c616e67756167653a20656e0d0a436f6e74656e742d4c656e6774683a203830300d0a446174653a204672692c2032322046656220323031392030333a31363a343320474d540d0a436f6e6e656374696f6e3a20636c6f73650d0a0d0a3c21646f63747970652068746d6c3e3c68746d6c206c616e673d22656e223e3c686561643e3c7469746c653e48545450205374617475732034303020e280932042616420526571756573743c2f7469746c653e3c7374796c6520747970653d22746578742f637373223e6831207b666f6e742d66616d696c793a5461686f6d612c417269616c2c73616e732d73657269663b636f6c6f723a77686974653b6261636b67726f756e642d636f6c6f723a233532354437363b666f6e742d73697a653a323270783b7d206832207b666f6e742d66616d696c793a5461686f6d612c417269616c2c73616e732d73657269663b636f6c6f723a77686974653b6261636b67726f756e642d636f6c6f723a233532354437363b666f6e742d73697a653a313670783b7d206833207b666f6e742d66616d696c793a5461686f6d612c417269616c2c73616e732d73657269663b636f6c6f723a77686974653b6261636b67726f756e642d636f6c6f723a233532354437363b666f6e742d73697a653a313470783b7d20626f6479207b666f6e742d66616d696c793a5461686f6d612c417269616c2c73616e732d73657269663b636f6c6f723a626c61636b3b6261636b67726f756e642d636f6c6f723a77686974653b7d2062207b666f6e742d66616d696c793a5461686f6d612c417269616c2c73616e732d73657269663b636f6c6f723a77686974653b6261636b67726f756e642d636f6c6f723a233532354437363b7d2070207b666f6e742d66616d696c793a5461686f6d612c417269616c2c73616e732d73657269663b6261636b67726f756e643a77686974653b636f6c6f723a626c61636b3b666f6e742d73697a653a313270783b7d2061207b636f6c6f723a626c61636b3b7d20612e6e616d65207b636f6c6f723a626c61636b3b7d202e6c696e65207b6865696768743a3170783b6261636b67726f756e642d636f6c6f723a233532354437363b626f726465723a6e6f6e653b7d3c2f7374796c653e3c2f686561643e3c626f64793e3c68313e48545450205374617475732034303020e280932042616420526571756573743c2f68313e3c2f626f64793e3c2f68746d6c3e
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1178) [netty-handler-4.1.31.Final.jar:4.1.31.Final]
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1243) [netty-handler-4.1.31.Final.jar:4.1.31.Final]
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:502) [netty-codec-4.1.31.Final.jar:4.1.31.Final]
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:441) [netty-codec-4.1.31.Final.jar:4.1.31.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:278) [netty-codec-4.1.31.Final.jar:4.1.31.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-transport-4.1.31.Final.jar:4.1.31.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChanne