背景:将前端http请求换成https请求,并以https请求后端,在开发环境中进行测试;
后端项目:Spring Cloud全家桶,利用Spring Gateway作为网关服务;
前端项目:利用node.js作为前端服务器请求后端;
一、后端:
1、利用keyTool生成自制证书;
1.1、打开cmd,输入命令:
keytool -genkey -alias client -keypass 123456 -keyalg RSA -storetype PKCS12 -keypass 123456 -storepass 123456 -keystore d:/client.p12 -ext san=dns:spam,ip:127.0.0.1
点击回车之后会按照下面步骤填写信息,可以随意填写,最后输入y确认信息,将会在d:/下生成client.p12 文件:
上面一个十分重要的点是:-ext san=dns:spam,ip:网关ip 这个命令,很多资料或者博客都会忽略这个参数,这是证书扩展信息,代表把证书生效的ip地址,不加上这一个命令将会出现以下情况:
a、配置证书之后,登录系统依旧不能成功,出现下图信息:
此时,解决办法也有,那就是,将请求的后端地址,在新打开的浏览器窗口中去执行一次,如下图所示,将该地址设置为例外或者叫受信任,但这种方式肯定不是我们所希望达到的效果:
b、除了a的情况,还会在f12中看到这种现象,原因是服务器证书中缺少“使用者可选名称”,需要在提交证书申请是加入该扩展信息,如下图所示:
1.2、生成了.p12的证书文件之后,由于不能直接将PKCS12格式的证书库导入,必须先把客户端证书导出为一个单独的CER文件,使用如下命令:
keytool -export -alias client -keystore d:/client.p12 -storetype PKCS12 -keypass 123456 -file d:/client.cer
自此,将会等到client.p12,client.cer两个文件,有了这两个文件,将可以进行移植到项目中使用;
附命令说明:
keytool
-genkey
-alias tomcat(别名)
-keypass 123456(别名密码)
-keyalg RSA(生证书的算法名称,RSA是一种非对称加密算法)
-keysize 1024(密钥长度,证书大小)
-validity 365(证书有效期,天单位)
-keystore W:/tomcat.keystore(指定生成证书的位置和证书名称)
-storepass 123456(获取keystore信息的密码)
-storetype (指定密钥仓库类型)
2、集成到项目中,将client.p12放入Spring Gateway网关的resources目录下,在Spring Gateway网关配置文件中加入以下配置:
server:
ssl:
key-store: classpath:client.p12
key-store-password: 123456
keyStoreType: PKCS12
keyAlias: client
spring:
cloud:
gateway:
httpclient:
ssl:
useInsecureTrustManager: true
并且,我们只需要前端到后端是https,网关路由到具体服务依旧利用http,所以还需要在Spring Gateway网关工程中加入以下配置类:
package com.cdmtc.filter;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;
import java.net.URI;
/**
* 网关调用内部工程时将https转成http
* @author : tanglin
* @date : 2019/10/16 11:30
*/
@Component
public class SchemeFilter implements GlobalFilter, Ordered {
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
Object uriObj = exchange.getAttributes().get(GATEWAY_REQUEST_URL_ATTR);
if (uriObj != null) {
URI uri = (URI) uriObj;
uri = this.upgradeConnection(uri, "http");
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, uri);
}
return chain.filter(exchange);
}
private URI upgradeConnection(URI uri, String scheme) {
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUri(uri).scheme(scheme);
if (uri.getRawQuery() != null) {
// When building the URI, UriComponentsBuilder verify the allowed characters and does not
// support the '+' so we replace it for its equivalent '%20'.
// See issue https://jira.spring.io/browse/SPR-10172
uriComponentsBuilder.replaceQuery(uri.getRawQuery().replace("+", "%20"));
}
return uriComponentsBuilder.build(true).toUri();
}
@Override
public int getOrder() {
return 10101;
}
}
自此,后端配置完成;如果加了证书之后,在启动网关服务时报编码解析等错误,需要在pom.xml的build中加入下面的依赖:
src/main/resources
false
certificate/*.jks
3、后端配置完成,需要将我们之前生成的client.cer文件导入到浏览器的“受信任的根证书颁发机构”中,双击client.cer文件,在弹窗中点击安装证书,之后按照弹窗依次选择“当前用户”—》“下一步”—》下一个弹窗中选择“将所有的证书都放入下列存储”,点击“浏览”,选择“受信任的 根证书颁发机构”,点击“确定”,再点击“下一步”:—》下一个弹窗中,点击“完成”,弹出确认框,选择“是”,将会 弹出“导入成功”提示;
二、前端配置:(node.js作为的前端服务器)
请参看下一篇博客:https://blog.csdn.net/qq_36608921/article/details/103069188
本文根据自己项目中实际情况撰写,其他类型的项目前端可能会有些许差别,但后端配置基本一样。