SpringBoot开启https
生成证书
首先新建一个文件,一定要提前新建,要不然会报错(回来补坑,后续的操作发现是不新建也可以,我也搞不明白了,都试试吧)
我是在D盘新建了zhengshu文件夹,文件夹下新建MetersPhereTestThree.keystore文件
keytool -genkeypair -alias MetersPhereTestThree -keypass 123456 -keyalg RSA -keysize 2048 -validity 36500 -keystore D:/zhengshu/MetersPhereTestThree.keystore
这个命令是jdk自带的,在cmd窗口执行即可
如果报错
keytool 错误: java.security.KeyStoreException: Unrecognized keystore format. Please load it with a specified type
我也不知道为什么,我的方式是删除文件再重建,且换个名字,同时把指令里的额名字也换了,然后打开新的cmd窗口,多试几次,就成功了
命令解释:
• -genkey 表示要创建一个新的密钥。
• -alias 表示 keystore 的别名。
• -keyalg 表示使用的加密算法是 RSA。
• -keysize 表示密钥的长度.。
• -keystore 表示生成的密钥存放位直。
• -validity 表示密钥的有效时间,单位为天。
•-storepass 指定访问密钥库的密码。
再次返回文件目录检查文件,文件内已经有内容了
SpringBoot配置文件
server:
# 项目访问的端口
port: 8765
servlet:
# 这个配置能够设置项目中的所有API的上下文路径(URL的一部分),与@RequestMapping有异曲同工之妙。
# 我们知道,@RequestMapping能够在API方法层级声明,同时能够在Controller的类层级声明,为什么能够在多层级声明呢?大家很容易想到,
# 为了使API url的语义性,遵从REST标准的API是非常棒的,同一个Controller下的URL前缀相同能够非常明确的表达语义与关联关系。
# 那么,如果我们有多个项目/微服务呢?也应该做到这一点,只不过是以更大的层级方式在应用。server.servlet.context-path能够以一个project为单位配置默认的URL上下文路径,
# 保持设计的一致性是非常合适的做法。
context-path: /ssl-service
ssl:
# 是否启用 ssl 支持 (默认是 true)
enabled: true
# 密钥库的路径
key-store: classpath:MetersPhereTestThree.keystore
# 用于访问密钥库的密码
key-store-password: 123456
# 密钥库类型
key-store-type: JKS
# 密钥库中密钥的别名
key-alias: MetersPhereTestThree
# 用于访问密钥库中密钥的密码
key-password: 123456
代码
entity
package com.meterspheretest.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Tiger {
public String name;
public Integer age;
}
controller
package com.meterspheretest.controller;
import com.meterspheretest.entity.Tiger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TigerController {
@GetMapping("getssl")
public Tiger getTigerInfo(){
Tiger tiger=new Tiger();
tiger.setAge(18);
tiger.setName("zhangsan");
return tiger;
}
}
发起https请求
启动SpringBoot项目,打开浏览器,访问接口
https://localhost:8765/ssl-service/getssl
http请求强制转换为https请求
首先,我们在配置中新增加一个专门给http请求用的端口,毕竟server.port端口已经被转化为https的端口了
server:
# 项目访问的端口
port: 8765
# 用于 非ssl请求 强制转成 ssl 请求
# 当使用 访问地址:http://127.0.0.1:8763/hello 访问时 后台会 将请求 转换成 https://127.0.0.1:8765/hello
# 而且这个是自己随便定义的,你也可以定义成http3.ports,随自己心情
http:
port: 8763
servlet:
# 这个配置能够设置项目中的所有API的上下文路径(URL的一部分),与@RequestMapping有异曲同工之妙。
# 我们知道,@RequestMapping能够在API方法层级声明,同时能够在Controller的类层级声明,为什么能够在多层级声明呢?大家很容易想到,
# 为了使API url的语义性,遵从REST标准的API是非常棒的,同一个Controller下的URL前缀相同能够非常明确的表达语义与关联关系。
# 那么,如果我们有多个项目/微服务呢?也应该做到这一点,只不过是以更大的层级方式在应用。server.servlet.context-path能够以一个project为单位配置默认的URL上下文路径,
# 保持设计的一致性是非常合适的做法。
context-path: /ssl-service
ssl:
# 是否启用 ssl 支持 (默认是 true)
enabled: true
# 密钥库的路径
key-store: classpath:MetersPhereTestThree.keystore
# 用于访问密钥库的密码
key-store-password: 123456
# 密钥库类型
key-store-type: JKS
# 密钥库中密钥的别名
key-alias: MetersPhereTestThree
# 用于访问密钥库中密钥的密码
key-password: 123456
然后再写一个配置类
package com.meterspheretest.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.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 代码参考的这位老哥的
* https://www.lmonkey.com/t/kyJ8pRdBe
* */
@Configuration
public class HttpToHttpsConfig {
/**
* 项目指定的端口号
*/
@Value("${server.port}")
private int serverPort;
/**
* 用于 非ssl请求 强制转成 ssl 请求 的端口号
*/
@Value("${server.http.port}")
private int port;
@Bean
public TomcatServletWebServerFactory servletWebServerFactory(){
TomcatServletWebServerFactory tomcatServletWebServerFactory=new TomcatServletWebServerFactory(){
@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);
}
};
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
//设置将分配给通过此连接器接收到的请求的方案
connector.setScheme("http");
//true: http使用http, https使用https;
//false: http重定向到https;
connector.setSecure(false);
//设置监听请求的端口号,这个端口不能其他已经在使用的端口重复,否则会报错
connector.setPort(port);
//重定向端口号(非SSL到SSL)
connector.setRedirectPort(serverPort);
tomcatServletWebServerFactory.addAdditionalTomcatConnectors(connector);
return tomcatServletWebServerFactory;
}
}
访问http链接
http://localhost:8763/ssl-service/getssl