spring boot支持https請求

spring boot給我們提供了很多便利之處,包括spring boot內置了tomcat,所以我們一般啓動都是spring boot內置的tomcat,用HTTP請求進行訪問,但是http請求並不安全,由於我們對項目應用的權限認證變得更加謹慎,需要用到https請求,自己新建了一個spring boot 項目進行測試,現在將怎麼新建spring boot工程和使用https請求以及在此過程中遇到的問題記錄一下。

一.新建spring boot 的web工程,我用的是intelij idea

1.創建一個項目,創建時選擇Spring Initializr,然後Next

image.png

 

2.填寫項目信息

image.png

3.選擇web工程

image.png

注:我的intelij版本可能比較低,出現的是這樣的,但是有的可能會出現下圖的,都是一樣的

image.png

4.填寫工程名字點擊finish

image.png

ok,一個新的web工程就建好了,下載依賴的過程比較慢

我們新建的是一個web工程,可以在項目的入口類加上@RestController註解,使之變爲一個Controller,然後裏邊提供一個地址轉換方法

 

@RestController
@SpringBootApplication
public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
    @RequestMapping(value = "/",produces = "text/plain;charset=UTF-8")
    String index(){
        return "Hello Spring Boot!";
    }
}

啓動main方法,訪問http://localhost:8080/(查看啓動日誌時可以發現默認的端口號是8080)可以看到頁面顯示

image.png

二.生成ssl證書

我是自己生成的ssl證書,當然這個證書是不被客戶端認可的
1.打開cmd,輸入生成證書的命令

 

keytool -genkey -alias tomcat  -storetype PKCS12 -keyalg RSA -keysize 2048  -keystore keystore.p12 -validity 3650

關於這幾個參數的解釋如下:

1.-storetype 指定密鑰倉庫類型
2.-keyalg 生證書的算法名稱,RSA是一種非對稱加密算法
3.-keysize 證書大小
4.-keystore 生成的證書文件的存儲路徑
5.-validity 證書的有效期

2.輸入密鑰庫口令

image.png

3.依次填寫證書相關的信息

image.png

完成之後,系統的當前用戶目錄下會生成一個keystore.p12文件,當然你在生成證書的時候可以改變證書的名稱,那麼相應的系統用戶目錄下就會生成相應的文件,將keystore.p12文件拷貝到我們項目的根路徑下,項目的結構如下:

image.png

4.修改application.properties文件,添加HTTPS支持

 

server.ssl.key-store=keystore.p12
server.ssl.key-store-password=123456
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias:tomcat

注:這裏的key-store-password就是我們生成ssl證書時設置的密鑰庫的口令

此時,我們的工程就支持了https請求,我們就可以啓動項目的main方法,查看啓動時的日誌會發現默認的端口依舊是8080,因爲我們並沒有額外設置https的端口號,訪問https://localhost:8080/

image.png

注:因爲我用的是自己生成的ssl證書,所以https請求是不被客戶端識別的,我用的是火狐瀏覽器,在警告頁點擊 高級按鈕,點擊添加例外,點擊確認安全例外就可以正常看到頁面顯示的內容,所以當你用瀏覽器進行https請求時未正常顯示並不是我們的項目有問題,修改瀏覽器的安全認證配置就行了

三.http請求轉換成https請求

我們已經習慣用http請求訪問,此時我們的項目支持的是https請求,爲了方便我們可以將訪問時的http請求轉換成https請求
在main方法中添加註解bean,代碼如下:

 

@RestController
@SpringBootApplication
public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
    @RequestMapping(value = "/",produces = "text/plain;charset=UTF-8")
    String index(){
        return "Hello Spring Boot!";
    }
    @Bean
    public EmbeddedServletContainerFactory servletContainer() {
        TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                SecurityConstraint constraint = new SecurityConstraint();
                constraint.setUserConstraint("CONFIDENTIAL");
                SecurityCollection collection = new SecurityCollection();
                collection.addPattern("/*");
                constraint.addCollection(collection);
                context.addConstraint(constraint);
            }
        };
        tomcat.addAdditionalTomcatConnectors(httpConnector());
        return tomcat;
    }

    @Bean
    public Connector httpConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setScheme("http");
        //Connector監聽的http的端口號
        connector.setPort(8080);
        connector.setSecure(false);
        //監聽到http的端口號後轉向到的https的端口號
        connector.setRedirectPort(8081);
        return connector;
    }

}

注:我們知道spring boot內置的tomcat啓動時的默認的端口號時8080,我們現在需要將http請求轉換成https請求,所以一定要區分端口號,我們在代碼中將http的端口號設置爲8080,在application.properties添加https的端口號

 

server.ssl.key-store=keystore.p12
server.ssl.key-store-password=123456
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias:tomcat
server.port=8081

啓動項目,我們訪問https://localhost:8081/,(同時還是需要設置瀏覽器的安全認證的)頁面可以正常顯示說明項目是支持https請求的

訪問http://localhost:8080/,我們可以看到頁面的url變成了https://localhost:8081/,頁面也可以正常顯示,說明我們的需求解決了,可以將http請求轉換成https請求。

四.同時支持http和https請求

如果我們想要項目同時支持http和https請求,就是說我們用http請求時不再轉換成https請求,同時還支持https請求,很簡單,我們只需要將代碼中的connector.setSecure(false)中的false改成true就可以了,代碼如下:

 

@RestController
@SpringBootApplication
public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
    @RequestMapping(value = "/",produces = "text/plain;charset=UTF-8")
    String index(){
        return "Hello Spring Boot!";
    }
    @Bean
    public EmbeddedServletContainerFactory servletContainer() {
        TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                SecurityConstraint constraint = new SecurityConstraint();
                constraint.setUserConstraint("CONFIDENTIAL");
                SecurityCollection collection = new SecurityCollection();
                collection.addPattern("/*");
                constraint.addCollection(collection);
                context.addConstraint(constraint);
            }
        };
        tomcat.addAdditionalTomcatConnectors(httpConnector());
        return tomcat;
    }

    @Bean
    public Connector httpConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setScheme("http");
        //Connector監聽的http的端口號
        connector.setPort(8080);
        connector.setSecure(true);
        //監聽到http的端口號後轉向到的https的端口號
        connector.setRedirectPort(8081);
        return connector;
    }

}

啓動項目,我們訪問https://localhost:8081/,頁面可以正常顯示說明項目是支持https請求的

訪問http://localhost:8080/,我們可以看到頁面的url並沒有轉換成https請求,頁面也可以正常顯示,說明我們的需求解決了,可以同時支持http和https請求。

如有問題,歡迎指正!!!!



作者:嗨_等風來
鏈接:https://www.jianshu.com/p/71cd01fa8438
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章