1.首先去腾讯云或者阿里云申请免费ssl证书,以腾讯云为例,不建议自己生成,因为没办法测试发布环境的效果,填写个人信息,最后提示审核中才是申请成功,审核比较快,半小时就通过了。
2.下载已经通过审核的证书文件夹,解压文件如下,根据项目选择使用:
3.因为springboot使用的是内置tomcat,所以我这边选择tomcat文件,在resources目录下导入xxx.jks
4.接下来配置properties文件,密码在同文件夹的keystorePass.txt中(腾讯云)
5.个人比较喜欢yml格式,简洁直观(阿里云)
6.到这个时候基本配置完成,但不能使用https后就通知所有人重新保存网址,这时候就需要增加请求转发,自动从http转到https
写法一:在启动类也就是@SpringBootApplication注解类中加上使用
/** * http重定向到https * @return */ @Bean public TomcatServletWebServerFactory servletContainer() { TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() { @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的端口号,也就是项目配置的port connector.setRedirectPort(8089); return connector; }
写法二:另外新建一个配置类,加上@Configuration注解声明
@Configuration public class TomcatConfig { @Bean TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() { TomcatEmbeddedServletContainerFactory factory = 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); } }; factory.addAdditionalTomcatConnectors(createTomcatConnector()); return factory; } private Connector createTomcatConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setScheme("http"); connector.setPort(5001); connector.setSecure(false); connector.setRedirectPort(443); return connector; } }
7.现在可以通过https://域名:8089/index访问,这样就看到熟悉的小锁了
注意:RestTemplate设置headers,访问https实现ssl请求参考:https://www.jianshu.com/p/beafe38428c7
application.properties配置:
#远程调用uri及ssl设置 httpClientUri=https://192.168.3.110:8081 #类型 httpClientSSL.keyStoreType=JKS #classpath下的文件名 httpClientSSL.keyFile= easyView.keystore #证书密码 httpClientSSL.keyPassword=xxxx
下面是自己封装的调用方法:
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContexts; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.ClassPathResource; import org.springframework.http.*; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import javax.net.ssl.SSLContext; import java.io.FileInputStream; import java.io.InputStream; import java.security.KeyStore; import java.util.Objects; import java.util.function.Consumer; /** * @date 2020/11/04 */ @Component public class HttpsUtil { private static Logger logger = LoggerFactory.getLogger(HttpsUtil.class); @Value("${httpClientSSL.keyStoreType}") private String keyStoreType; @Value("${httpClientSSL.keyFile}") private String keyFile; @Value("${httpClientSSL.keyPassword}") private String keyPassword; @Value("${httpClientUri}") private String url; public static final String GET = "GET"; public static final String POST = "POST"; public static final String PUT = "PUT"; /** * RestTemplate访问https请求 * * @param data * @param addHeader * @return */ public String transferRestTemplate(String path, String data, String httpMethod, Consumer<HttpHeaders> addHeader) { String body = null; try { KeyStore keyStore = KeyStore.getInstance(keyStoreType); ClassPathResource resource = new ClassPathResource(keyFile); InputStream inputStream = new FileInputStream(resource.getFile()); keyStore.load(inputStream,keyPassword.toCharArray()); SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keyStore, TrustSelfSignedStrategy.INSTANCE).build(); // Allow TLSv1 protocol only SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslcontext); CloseableHttpClient httpclient = HttpClients.custom() .setSSLSocketFactory(socketFactory) .build(); HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpclient); RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory); HttpHeaders requestHeaders = new HttpHeaders(); addHeader.accept(requestHeaders); requestHeaders.setContentType(MediaType.APPLICATION_JSON); HttpEntity<String> httpEntity = new HttpEntity<>(data, requestHeaders); ResponseEntity<String> response = null; switch(httpMethod){ case HttpsUtil.GET : response = restTemplate.exchange(url+ path, HttpMethod.GET, httpEntity, String.class); break; case HttpsUtil.POST : response = restTemplate.exchange(url+ path, HttpMethod.POST, httpEntity, String.class); break; case HttpsUtil.PUT : response = restTemplate.exchange(url+ path, HttpMethod.PUT, httpEntity, String.class); break; default: logger.error("非法请求方式:", new IllegalStateException(httpMethod)); } if (Objects.nonNull(response)) { if (response.getStatusCode().is2xxSuccessful()) { body = response.getBody(); } logger.info("返回状态码: {}, 返回数据: {}", response.getStatusCodeValue(), body); }else { logger.info("response is null"); } }catch (Exception e) { logger.error("https请求错误:", e); } return body; } }
8.通过域名访问失败原因及解决办法
- 域名未配置解析,去域名管理配置解析,10分钟后通过ping 域名看是否显示ip,显示则解析成功!
- 域名未认证,去域名管理上传个人信息进行域名实名!
- 域名已实名但未网站未备案,解决办法
- 去进行网站实名,使用腾讯云小程序认证进行icp备案即可!
- 可以通过域名访问但必须加上自定义端口才行,不能使用8080或443等默认端口,否则提示连接已重置!