SpringBoot 集成 Https (基于 tomcat)
文章目录
1 缘起
本人在使用开源项目 kkFileView (https://gitee.com/kekingcn/file-online-preview), 过程中发现这个问题
- Mixed Content: The page at ‘https://xxx’ was loaded over HTTPS, but requested an insecure resource ‘http://xx:xx/onlinePreview?url=xxxx’. This request has been blocked; the content must be served over HTTPS.
因为https协议站点,读取的资源文件js css png,包括请求post和get,还有iframe的页面,都必须是https协议的。所以就会报出下面的错误,而我把 kkFileView 预览页面引入了(http 页面),导致报错
2 解决方案
- 修改 kkFileView 项目 支持 https 的预览
因为 kkFileView 基于 springboot 1.5.x , 所以笔者采用了 1.5.x 的解决方案,springboot 2.0 以后有所区别
3 具体代码
3.1 HttpsConfig
package cn.keking.config;
import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* https 自动装配类, 基于 spring 1.5.x
*
* @description
* @author: huangwenjun
* @create: 2019-06-20 13:53
**/
@Configuration
@ConditionalOnExpression("${server.ssl.enabled} == true")
public class HttpsConfig {
@Value("${server.http.port}")
private Integer httpPort;
@Value("${server.port}")
private Integer httpsPort;
/**
* it's for set http url auto change to https
*/
@Bean
public EmbeddedServletContainerFactory servletContainer(){
TomcatEmbeddedServletContainerFactory tomcat=new TomcatEmbeddedServletContainerFactory(){
@Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint=new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection=new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(httpConnector());
return tomcat;
}
@Bean
public Connector httpConnector(){
Connector connector=new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(httpPort);
connector.setSecure(false);
connector.setRedirectPort(httpsPort);
return connector;
}
}
3.2 新增配置文件
#https配置
server.http.port=8012
server.port=8443
server.ssl.enabled=true
server.ssl.key-store=classpath:tomcat.keystore
server.ssl.key-store-password=123456
server.ssl.key-password=123456
server.ssl.key-store-type=JKS
3.3 将 生成的 tomcat.keystore 拷贝到 resources 目录下
关于 keystore 生成
4 可能碰到的问题
- java.io.IOException: Invalid keystore format
这是因为 maven 打包的时候对 二进制文件 tomcat.keystore 进行编码,导致文件不可用
- 解决方案
(https://blog.csdn.net/kevin_mails/article/details/84590449)
1 手动替换 tomcat.keystore
2 修改 maven 的打包配置
<!--排除tomcat.keystore,不打包到classpath下,自然就不会过滤-->
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>tomcat.keystore</exclude>
</excludes>
</resource>
<!--将tomcat.keystore打包到classpath下,但是不进行资源过滤-->
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>tomcat.keystore</include>
</includes>
</resource>