参考:
Nginx 服务器 SSL 证书安装部署
浏览器报Mixed Content错误的解决
使用SpringBoot配置https(SSL证书)
配置SpringBoot同时支持http和https访问
Springboot配置SSL(https)
Nginx配置同一个域名同时支持http与https两种方式访问。
申请证书
1、腾讯云/阿里云申请免费 ssl 证书
2、下载证书
下载 Tomcat(JKS)、Nginx 证书,解压。格式:域名_nginx
、域名_jks
前端 nginx 配置
我的 vue 项目是放到 docker 的 nginx 容器运行的
1、拷贝证书
找到 nginx 证书的 xxx_bundle.crt
证书文件和 xxx.key
私钥文件,拷贝到 nginx 容器(我的容器名是 vueblog_frontend
)的 /etc/nginx
目录下。(我的 nginx 版本是 1.21)
docker cp heart-go.cn_bundle.crt vueblog_frontend:/etc/nginx/
docker cp heart-go.cn.key vueblog_frontend:/etc/nginx/
2、进入 nginx 容器修改配置
docker exec -it vueblog_frontend /bin/bash
cd /etc/nginx/conf.d/
vim default.conf
若没有 vim,可以
apt-get install vim
安装一个。
nginx 配置如下,修改为你的域名和证书名。
保存退出。
测试 nginx
$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
3、重载 nginx 配置
nginx -s reload
到这里前端 vue 项目的 ssl 证书就配置完了。
4、端口映射
exit
退出容器,给 nginx 容器添加一个 443 的端口映射
docker 给运行的容器加端口映射
curl 也正常。
5、配置 nginx 让 http 访问自动跳转到 https
http 是不安全的连接,一般都推荐使用 https。
所以我们在用户使用 http 访问网站的时候,做一个跳转。
打开nginx配置
docker exec -it vueblog_frontend /bin/bash
cd /etc/nginx/conf.d/
vim default.conf
注释掉原有 server 的 80 端口监听
添加一个新的 server 配置,监听80端口并重定向到 https 访问地址。
让配置生效
nginx -t
nginx -s reload
此时使用 http 访问网站,就会自动跳转到 https 地址。
后端 springboot 项目配置 SSL 证书
此时用 https 访问我们的前端 vue 项目,出现了后端接口调用失败的情况。
在浏览器 console 看到报错:
Mixed Content: The page at 'https://heart-go.cn/login' was loaded over HTTPS, but requested an insecure resource 'http://xxx'. This request has been blocked; the content must be served over HTTPS.
https 地址中,如果加载了 http 资源,浏览器将认为这是不安全的资源,将会默认阻止。
我们之前的后端接口是直接 http协议://ip:端口
调用的,现在也得支持 ssl 访问才行。
1、修改前端接口请求地址
在配置之前,先把前端项目的接口请求地址修改一下。
http 改成 https,ip 改成域名。
2、证书文件扔到 resource
然后打开后端 springboot 项目,把我们下载的 Tomcat(JKS)证书里的 xxx.jks 证书文件扔到 resource 下。
3、修改 springboot 配置文件
修改你的项目配置文件 application.propertiesserver.ssl.key-store
是你的证书路径server.ssl.key-store-password
是你下载的证书里 keystorePass.txt 文件的内容
注意不是 server.ssl.key-password
4、docker 容器端口映射
然后新建一个配置类,做一下端口映射,添加一个新的 8082 端口另外支持 http 访问。
package com.libaiyun.config;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.catalina.connector.Connector;
/**
* SSL访问端口映射
*/
@Configuration
public class SSLConfig {
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
tomcat.addAdditionalTomcatConnectors(createHTTPConnector());
return tomcat;
}
private Connector createHTTPConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
//同时启用http(8082)、https(8081)两个端口
connector.setScheme("http");
connector.setSecure(false);
connector.setPort(8082);
connector.setRedirectPort(8081);
return connector;
}
}
5、测试
打包上线,此时我们可以 curl https 监听端口
curl https://heart-go.cn/8081
或者 curl http 监听端口
curl http://heart-go.cn/8082
都可以正常访问后端接口。(如果是 docker 运行的话记得给新增的 http 端口 8082 也添加映射~)
本地生成 SSL 证书并给 springboot 配置
除了上述申请受信任机构的 ssl 证书,我们也可以选择自己本地生成一个。(二选一即可)
1、生成密钥证书
打开cmd,执行
keytool -genkey -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
keytool 是 jdk 的工具,安装好 jdk 可以找到
alias:密钥别名
storetype:指定密钥仓库类型
keyalg:生成证书的算法名称,RSA是一种非对称加密算法
keysize:证书大小
keystore:生成的证书文件的存储路径
validity:证书的有效期
接着输入证书密码(记下)、证书信息(随意填,浏览器中查看证书时会显示)
2、配置 springboot
将生成的密钥证书拷贝到项目中的 resource 中
修改项目配置文件 application.properties
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=证书密码
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias=tomcat
启动访问即可,注意这种本地生成的 SSL 证书放到浏览器上会显示不受信任的机构颁发的证书。
当然仅用于后端接口 ssl 支持,则无需在意。
SSL 相关
1、ssl 证书是带有域名/IP 信息的
记住我们的 ssl 证书是带有域名/IP 信息的,如果
curl https://121.4.119.108:8081
或者
curl https://localhost:8081
这样的形式,都是会出现 ssl 错误的,因为域名和证书对不上。
$ curl https://121.4.119.108:8081
curl: (60) schannel: SNI or certificate check failed: SEC_E_WRONG_PRINCIPAL > (0x80090322) - 目标主要名称不正确。
More details here: https://curl.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
当然我们给 curl 加上 -k 参数就可以忽略 ssl 错误正常访问。
体现到前端访问上,ssl 错误就会显示网站不安全。
当然只是作为后端接口调用,其实也没什么问题。我们依旧可以用 ip 作为 HTTPS 接口地址。
2、一个端口同时只支持一种协议
一个端口同时只支持一种协议,比如上面我们监听 8081 使用ssl协议,监听 8080 使用 http 协议。
HTTP 协议是应用层的,端口是传输层,数据从高到低层层封包,传输过去再由低到高层层解包,这部分可以去看下 OSI 七层模型和 TCP/IP 模型及对应协议
如果我们使用 HTTP 协议去访问 HTTPS 端口,就会出错
$ curl http://121.4.119.108:8081/
Bad Request
This combination of host and port requires TLS.
反之,我们使用 HTTPS 协议去访问 HTTP 端口,也会报错
$ curl https://121.4.119.108:8082/
curl: (35) schannel: next InitializeSecurityContext failed: SEC_E_INVALID_TOKEN (0x80090308) - 给函数提供的标志无效
如果想让一个端口同时支持 HTTP 和 HTTPS 访问,就得用到 nginx 了。
Nginx 实现一个端口同时支持 HTTP 和 HTTPS 访问
over
到这里后端配置 SSL 也结束,我们把前后端项目都上线,测试正常访问。
原创文章,作者:,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/273320.html