add JSSESSLContext

This commit is contained in:
Looly 2024-12-22 22:38:17 +08:00
parent ba5826436a
commit dea810e933
3 changed files with 132 additions and 8 deletions

View File

@ -142,7 +142,7 @@
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId> <artifactId>slf4j-simple</artifactId>
<version>2.0.9</version> <version>1.7.36</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 2024 Hutool Team and hutool.cn
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dromara.hutool.http.server.engine.tomcat;
import org.apache.tomcat.util.net.SSLContext;
import javax.net.ssl.*;
import java.security.KeyManagementException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* Tomcat SSLContext实现
*
* @author looly
* @since 6.0.0
*/
public class JSSESSLContext implements SSLContext {
private final javax.net.ssl.SSLContext context;
private KeyManager[] kms;
private TrustManager[] tms;
/**
* 构造
*
* @param context SSLContext
*/
public JSSESSLContext(final javax.net.ssl.SSLContext context) {
this.context = context;
}
@Override
public void init(final KeyManager[] kms, final TrustManager[] tms, final SecureRandom sr)
throws KeyManagementException {
this.kms = kms;
this.tms = tms;
context.init(kms, tms, sr);
}
@Override
public void destroy() {
}
@Override
public SSLSessionContext getServerSessionContext() {
return context.getServerSessionContext();
}
@Override
public SSLEngine createSSLEngine() {
return context.createSSLEngine();
}
@Override
public SSLServerSocketFactory getServerSocketFactory() {
return context.getServerSocketFactory();
}
@Override
public SSLParameters getSupportedSSLParameters() {
return context.getSupportedSSLParameters();
}
@Override
public X509Certificate[] getCertificateChain(final String alias) {
X509Certificate[] result = null;
if (kms != null) {
for (int i = 0; i < kms.length && result == null; i++) {
if (kms[i] instanceof X509KeyManager) {
result = ((X509KeyManager) kms[i]).getCertificateChain(alias);
}
}
}
return result;
}
@Override
public X509Certificate[] getAcceptedIssuers() {
final Set<X509Certificate> certs = new HashSet<>();
if (tms != null) {
for (final TrustManager tm : tms) {
if (tm instanceof X509TrustManager) {
final X509Certificate[] accepted = ((X509TrustManager) tm).getAcceptedIssuers();
certs.addAll(Arrays.asList(accepted));
}
}
}
return certs.toArray(new X509Certificate[0]);
}
}

View File

@ -24,12 +24,16 @@ import org.apache.catalina.connector.Response;
import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.valves.ValveBase; import org.apache.catalina.valves.ValveBase;
import org.apache.coyote.http11.Http11NioProtocol; import org.apache.coyote.http11.Http11NioProtocol;
import org.apache.tomcat.util.net.SSLHostConfig;
import org.apache.tomcat.util.net.SSLHostConfigCertificate;
import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.http.HttpException; import org.dromara.hutool.http.HttpException;
import org.dromara.hutool.http.server.ServerConfig; import org.dromara.hutool.http.server.ServerConfig;
import org.dromara.hutool.http.server.engine.AbstractServerEngine; import org.dromara.hutool.http.server.engine.AbstractServerEngine;
import javax.net.ssl.SSLContext;
/** /**
* Tomcat引擎实现 * Tomcat引擎实现
* *
@ -88,20 +92,18 @@ public class TomcatEngine extends AbstractServerEngine {
tomcat.setHostname(config.getHost()); tomcat.setHostname(config.getHost());
tomcat.setBaseDir(config.getRoot()); tomcat.setBaseDir(config.getRoot());
initConnector(tomcat); tomcat.setConnector(createConnector());
initContext(tomcat); initContext(tomcat);
// TODO 配置支持HTTPS
this.tomcat = tomcat; this.tomcat = tomcat;
} }
/** /**
* 初始化Connector * 创建Connector
* *
* @param tomcat Tomcat * @return Connector
*/ */
private void initConnector(final Tomcat tomcat) { private Connector createConnector() {
final ServerConfig config = this.config; final ServerConfig config = this.config;
final Http11NioProtocol protocol = new Http11NioProtocol(); final Http11NioProtocol protocol = new Http11NioProtocol();
final int maxHeaderSize = config.getMaxHeaderSize(); final int maxHeaderSize = config.getMaxHeaderSize();
@ -120,7 +122,21 @@ public class TomcatEngine extends AbstractServerEngine {
connector.setMaxPostSize(maxBodySize); connector.setMaxPostSize(maxBodySize);
} }
tomcat.setConnector(connector); // SSL配置
final SSLContext sslContext = config.getSslContext();
if(null != sslContext){
final SSLHostConfig sslHostConfig = new SSLHostConfig();
final SSLHostConfigCertificate sslHostConfigCertificate =
new SSLHostConfigCertificate(sslHostConfig, SSLHostConfigCertificate.Type.RSA);
sslHostConfigCertificate.setSslContext(new JSSESSLContext(sslContext));
sslHostConfig.addCertificate(sslHostConfigCertificate);
connector.addSslHostConfig(sslHostConfig);
connector.setScheme("https");
connector.setSecure(true);
connector.setPort(config.getPort());
}
return connector;
} }
/** /**