前言
接上一篇的安全加固之https http://www.jianshu.com/p/46cad1265561 之后,今天我们来讨论一下spring boot微服务怎么来支持https调用。
BTW: 我们的重点是讨论服务之间https调用的解决方案。
ssl证书
spring boot的application.yml提供了一下几个选项,来用于支持https
server.ssl.key-store
server.ssl.key-store-password
server.ssl.trust-store
server.ssl.trust-store-password
从配置上面,我们就可以看到,需要key-store、trust-store
那么就来生成这些,上次的那篇文章,我们得到了root.key root.crt根证书
#生成服务端私钥和证书申请请求
openssl genrsa -out server.key 2048
openssl req -new -key server.key -subj "/C=CN/ST=ZheJiang/L=HangZhou/O=Xiaobaxi/OU=GA/CN=xiaobaxi.com" -out server.csr
#使用根证书签发服务端证书
openssl x509 -req -in server.csr -CA root.crt -CAkey root.key -CAcreateserial -out server.crt -days 1825 -extensions SAN -extfile san.cnf
# 生成pkcs12
openssl pkcs12 -export -in server.crt -inkey server.key -out server.pkcs12
# pkcs12 -> jks
keytool -importkeystore -srckeystore /opt/ca/server.pkcs12 -destkeystore server.jks -srcstoretype pkcs12
# trust strore
keytool -importcert -alias ca -file /opt/ca/root.crt -keystore servertrust.jks
关于java ssl/tls相关内容,本文不做过多的讨论,可以查看http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html
配置证书
将server.jks跟servertrust.jks拷贝到微服务的classpath目录下
配置微服务的application.yml,增加ssl的相关配置,我们不是金融支付类的,选择简单一点:单向认证
server:
port: 8443
ssl:
enabled: true
client-auth: want #这个地方,我们选择简单点
key-store: classpath:server.jks
key-store-password: 123456
trust-store: classpath:servertrust.jks
trust-store-password: 123456
使用FeignClient进行调用
feign默认的底层发送http请求用的是JDK的URLConnetion,参见feign-core包中的Client接口以及Default内部类实现
如果想通过HttpClient或者OkHttpClient来作为feign底层发送http请求的实现,则在org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientAutoConfiguration这个配置类中,有对这两个类的实现进行了封装:
HttpClient配置:
OkHttpClient也是类似的配置
那我们就对这两个配置进行修改
通过@Configuration的配置类实现OkHttpClient、HttpClient的ssl功能
OkHttpClient也是同理的配置,也是load trustStore -- X509TrustManager -- SSLSocketFactory -- OkHttpClient build这样的流程
接下去,通过Enable的方式来动态启停这个配置,默认为HttpClient
那如何在OkHttpClient、HttpClient两个之中进行选择呢,采用ImportSelector的selectImports方法来进行选用哪个配置
最后,将这些配置封装成starter,以方便别的服务进行应用配置,哦,别忘记了,@FeignClient的value中需要配置https啦
需要注意的是,一般情况下内网服务调用不走https,通过api网关来做。算是做一个小测试。
BTW:感谢金童鞋的支持~~~