在本教程中,我们将向您展示如何为Spring Boot Web应用程序(mvc + thymeleaf)启用SSL(HTTPS)支持。
经过测试
- Maven 3
- Java 8
- Spring Boot 2.2.4。发布
- Spring Boot默认嵌入式Tomcat 9
- 自签名证书(PKCS12)
要为Spring Boot Web应用程序启用SSL或HTTPS,请将证书文件.p12
或.jks
放在resources
文件夹中,并在application.properties
声明server.ssl.*
值。
# SSL
server.port=8443
server.ssl.key-store=classpath:cert.p12
server.ssl.key-store-password=123456
# JKS or PKCS12
server.ssl.keyStoreType=PKCS12
# Spring Security
# security.require-ssl=true
完成,启动Spring Boot,并访问https://localhost:8443
PEM文件
.pem
是适用于Apache和Nginx的流行证书格式,但Java不支持。以下是使用OpenSSL将.pem
转换为.p12
格式的示例。
1.自签名证书
在此示例中,我们将使用JDK的keytool
生成PKCS12格式的自签名证书。 下面的命令将创建一个名为mkyong.p12
的PKCS12证书,将该文件放入resources
文件夹中。
$ keytool -genkeypair -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore mkyong.p12 -validity 365
Enter keystore password:
Re-enter new password:
What is your first and last name?
[Unknown]: yong
What is the name of your organizational unit?
[Unknown]: mkyong
What is the name of your organization?
[Unknown]: mkyong
What is the name of your City or Locality?
[Unknown]:
What is the name of your State or Province?
[Unknown]:
What is the two-letter country code for this unit?
[Unknown]:
Is CN=yong, OU=mkyong, O=mkyong, L=Unknown, ST=Unknown, C=Unknown correct?
[no]: yes
注意
更多keytool用法
2.项目目录
2.1标准的Maven项目结构。

3. Maven
3.1标准的Spring Boot依赖关系。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mkyong</groupId>
<artifactId>spring-boot-ssl</artifactId>
<version>1.0</version>
<name>spring-boot-ssl</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- debugging -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<finalName>spring-boot-web</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
4.Spring启动
4.1启动@SpringBootApplication
,并返回一个控制器。
package com.mkyong;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@SpringBootApplication
@Controller
public class StartApplication {
@GetMapping("/")
public String index(final Model model) {
model.addAttribute("title", "Spring Boot + SSL (HTTPS)");
model.addAttribute("msg", "Welcome to the SSL!");
return "index";
}
public static void main(String[] args) {
SpringApplication.run(StartApplication.class, args);
}
}
4.2百里香页。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"/>
<link data-th-href="@{/css/main.css}" rel="stylesheet">
<title>Spring Boot SSL Examples</title>
</head>
<body>
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="#">Mkyong.com</div></a>
</nav>
<main role="main" class="container">
<div class="starter-template">
<h1 th:text="${title}">Default title.</h1>
<p th:text="${msg}">Default text.</p>
</div>
</main>
<script data-th-src="@{/js/main.js}"></script>
</body>
</html>
5. application.properties
# SSL
server.port=8443
server.ssl.key-store=classpath:mkyong.p12
server.ssl.key-store-password=123456
# PKCS12 or JKS
server.ssl.keyStoreType=PKCS12
# Spring Security
# security.require-ssl=true
6.运行Spring Boot + SSL
$ cd project
$ mvn clean package
$ java -jar target/spring-boot-web.jar
...
com.mkyong.StartApplication : No active profile set, falling back to default profiles: default
o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8443 (https)
o.apache.catalina.core.StandardService : Starting service [Tomcat]
org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.30]
o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 571 ms
o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8443 (https) with context path ''
com.mkyong.StartApplication : Started StartApplication in 1.297 seconds (JVM running for 1.65)
访问https://localhost:8443


由于具有自签名证书,浏览器将显示警告,指出证书无效,将其忽略,然后单击“高级…继续”继续。
注意
要解决浏览器警告问题,请从Let's Encrypt获得免费证书,或从可信任的CA(例如Comodo或GeoTrust)购买证书。 阅读有关SSL证书颁发机构的更多信息。
7.常见问题
将所有流量从端口8080重定向到8443。
package com.mkyong;
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.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class StartApplication {
public static void main(String[] args) {
SpringApplication.run(StartApplication.class, args);
}
// spring boot 2.x
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = 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);
}
};
tomcat.addAdditionalTomcatConnectors(redirectConnector());
return tomcat;
}
private Connector redirectConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(8443);
return connector;
}
}
下载源代码
$ git clone https://github.com/mkyong/spring-boot
$ cd spring-boot-ssl
$ mvn清洁包
$ java -jar target / spring-boot-web.jar
访问https:// localhost:8443
参考文献
翻译自: https://mkyong.com/spring-boot/spring-boot-ssl-https-examples/