zoukankan      html  css  js  c++  java
  • Spring Boot项目如何同时支持HTTP和HTTPS协议

    本文首发于个人网站:Spring Boot项目如何同时支持HTTP和HTTPS协议

    如今,企业级应用程序的常见场景是同时支持HTTP和HTTPS两种协议,这篇文章考虑如何让Spring Boot应用程序同时支持HTTP和HTTPS两种协议。

    准备

    为了使用HTTPS连接器,需要生成一份Certificate keystore,用于加密和机密浏览器的SSL沟通。

    如果你使用Unix或者Mac OS,可以通过下列命令:keytool -genkey -alias tomcat -keyalg RSA,在生成过程中可能需要你填入一些自己的信息,例如我的机器上反馈如下:

    生成kestore

    可以看出,执行完上述命令后在home目录下多了一个新的.keystore文件。

    实战

    • 首先在resources目录下新建一个配置文件tomcat.https.properties,用于存放HTTPS的配置信息;
    custom.tomcat.https.port=8443
    custom.tomcat.https.secure=true
    custom.tomcat.https.scheme=https
    custom.tomcat.https.ssl=true
    custom.tomcat.https.keystore=${user.home}/.keystore
    custom.tomcat.https.keystore-password=changeit
    
    • 然后在WebConfiguration类中创建一个静态类TomcatSslConnectorProperties
    @ConfigurationProperties(prefix = "custom.tomcat.https")
    public static class TomcatSslConnectorProperties {
        private Integer port;
        private Boolean ssl = true;
        private Boolean secure = true;
        private String scheme = "https";
        private File keystore;
        private String keystorePassword;
        //这里为了节省空间,省略了getters和setters,读者在实践的时候要加上
        
        public void configureConnector(Connector connector) {
            if (port != null) {
                connector.setPort(port);
            }
            if (secure != null) {
                connector.setSecure(secure);
            }
            if (scheme != null) {
                connector.setScheme(scheme);
            }
            if (ssl != null) {
                connector.setProperty("SSLEnabled", ssl.toString());
            }
            if (keystore != null && keystore.exists()) {
                connector.setProperty("keystoreFile", keystore.getAbsolutePath());
                connector.setProperty("keystorePassword", keystorePassword);
            }
        }
    }
    
    • 通过注解加载tomcat.https.properties配置文件,并与TomcatSslConnectorProperties绑定,用注解修饰WebConfiguration类;
    @Configuration
    @PropertySource("classpath:/tomcat.https.properties")
    @EnableConfigurationProperties(WebConfiguration.TomcatSslConnectorProperties.class)
    public class WebConfiguration extends WebMvcConfigurerAdapter {...}
    
    • 在WebConfiguration类中创建EmbeddedServletContainerFactory类型的Srping bean,并用它添加之前创建的HTTPS连接器。
    @Bean
    public EmbeddedServletContainerFactory servletContainer(TomcatSslConnectorProperties properties) {
        TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
        tomcat.addAdditionalTomcatConnectors(createSslConnector(properties));
        return tomcat;
    }
    
    private Connector createSslConnector(TomcatSslConnectorProperties properties) {
        Connector connector = new Connector();
        properties.configureConnector(connector);
        return connector;
    }
    
    • 通过mvn spring-boot:run启动应用程序;
    • 在浏览器中访问URLhttps://localhost:8443/internal/tomcat.https.properties

    支持HTTPS协议

    • 在浏览器中访问URLhttp://localhost:8080/internal/application.properties

    同时支持HTTP协议

    分析

    根据之前的文章和官方文档,Spring Boot已经对外开放了很多服务器配置,这些配置信息通过Spring Boot内部的ServerProperties类完成绑定,若要参考Spring Boot的通用配置项,请点击这里

    Spring Boot不支持通过application.properties同时配置HTTP连接器和HTTPS连接器。在官方文档70.8中提到一种方法,是将属性值硬编码在程序中。

    因此我们这里新建一个配置文件tomcat.https.properties来实现,但是这并不符合“Spring Boot风格”,后续有可能应该会支持“通过application.properties同时配置HTTP连接器和HTTPS连接器”。我添加的TomcatSslConnectorProperties是模仿Spring Boot中的ServerProperties的使用机制实现的,这里使用了自定义的属性前缀custom.tomcat而没有用现有的server.前缀,因为ServerProperties禁止在其他的配置文件中使用该命名空间。

    @ConfigurationProperties(prefix = "custom.tomcat.https")这个注解会让Spring Boot自动将custom.tomcat.https开头的属性绑定到TomcatSslConnectorProperties这个类的成员上(确保该类的getters和setters存在)。值得一提的是,在绑定过程中Spring Boot会自动将属性值转换成合适的数据类型,例如custom.tomcat.https.keystore的值会自动绑定到File对象keystore上。

    使用@PropertySource("classpath:/tomcat.https.properties")来让Spring Boot加载tomcat.https.properties文件中的属性。

    使用@EnableConfigurationProperties(WebConfiguration.TomcatSslConnectorProperties.class)让Spring Boot自动创建一个属性对象,包含上述通过@PropertySource导入的属性。

    在属性值导入内存,并构建好TomcatSslConnectorProperties实例后,需要创建一个EmbeddedServletContainerFactory类型的Spring bean,用于创建EmbeddedServletContainer。

    通过createSslConnector方法可以构建一个包含了我们指定的属性值的连接器,然后通过tomcat.addAdditionalTomcatConnectors(createSslConnector(properties));设置tomcat容器的HTTPS连接器。

    参考资料

    1. 配置SSL

    Spring Boot 1.x系列

    1. Spring Boot的自动配置、Command-line-Runner
    2. 了解Spring Boot的自动配置
    3. Spring Boot的@PropertySource注解在整合Redis中的使用
    4. Spring Boot项目中如何定制HTTP消息转换器
    5. Spring Boot整合Mongodb提供Restful接口
    6. Spring中bean的scope
    7. Spring Boot项目中使用事件派发器模式
    8. Spring Boot提供RESTful接口时的错误处理实践
    9. Spring Boot实战之定制自己的starter

    本号专注于后端技术、JVM问题排查和优化、Java面试题、个人成长和自我管理等主题,为读者提供一线开发者的工作和成长经验,期待你能在这里有所收获。
    javaadu

  • 相关阅读:
    C# log4net 的配置
    C# 泛型
    Word 2013 基本概念与常用操作
    DataGridViewComboBoxColumn 事件过程分析
    C#垃圾回收机制
    Ceph分布式存储之三-S3接口编程
    .NET特性(Attribute)的应用
    24.Odoo产品分析 (三) – 人力资源板块(5) – 出勤(1)
    23.Odoo产品分析 (三) – 人力资源板块(4) – 招聘流程(1)
    22.Odoo产品分析 (三) – 人力资源板块(3) – 休假管理(1)
  • 原文地址:https://www.cnblogs.com/javaadu/p/11746888.html
Copyright © 2011-2022 走看看