spring SslServerCustomizer 源码
springboot SslServerCustomizer 代码
文件路径:/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizer.java
/*
* Copyright 2012-2022 the original author or authors.
*
* 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
*
* https://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.springframework.boot.web.embedded.jetty;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.URL;
import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http2.HTTP2Cipher;
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.springframework.boot.web.server.Http2;
import org.springframework.boot.web.server.Ssl;
import org.springframework.boot.web.server.SslConfigurationValidator;
import org.springframework.boot.web.server.SslStoreProvider;
import org.springframework.boot.web.server.WebServerException;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ResourceUtils;
/**
* {@link JettyServerCustomizer} that configures SSL on the given Jetty server instance.
*
* @author Brian Clozel
* @author Olivier Lamy
* @author Chris Bono
*/
class SslServerCustomizer implements JettyServerCustomizer {
private final InetSocketAddress address;
private final Ssl ssl;
private final SslStoreProvider sslStoreProvider;
private final Http2 http2;
SslServerCustomizer(InetSocketAddress address, Ssl ssl, SslStoreProvider sslStoreProvider, Http2 http2) {
this.address = address;
this.ssl = ssl;
this.sslStoreProvider = sslStoreProvider;
this.http2 = http2;
}
@Override
public void customize(Server server) {
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setEndpointIdentificationAlgorithm(null);
configureSsl(sslContextFactory, this.ssl, this.sslStoreProvider);
ServerConnector connector = createConnector(server, sslContextFactory, this.address);
server.setConnectors(new Connector[] { connector });
}
private ServerConnector createConnector(Server server, SslContextFactory.Server sslContextFactory,
InetSocketAddress address) {
HttpConfiguration config = new HttpConfiguration();
config.setSendServerVersion(false);
config.setSecureScheme("https");
config.setSecurePort(address.getPort());
config.addCustomizer(new SecureRequestCustomizer());
ServerConnector connector = createServerConnector(server, sslContextFactory, config);
connector.setPort(address.getPort());
connector.setHost(address.getHostString());
return connector;
}
private ServerConnector createServerConnector(Server server, SslContextFactory.Server sslContextFactory,
HttpConfiguration config) {
if (this.http2 == null || !this.http2.isEnabled()) {
return createHttp11ServerConnector(server, config, sslContextFactory);
}
Assert.state(isJettyAlpnPresent(),
() -> "An 'org.eclipse.jetty:jetty-alpn-*-server' dependency is required for HTTP/2 support.");
Assert.state(isJettyHttp2Present(),
() -> "The 'org.eclipse.jetty.http2:http2-server' dependency is required for HTTP/2 support.");
return createHttp2ServerConnector(server, config, sslContextFactory);
}
private ServerConnector createHttp11ServerConnector(Server server, HttpConfiguration config,
SslContextFactory.Server sslContextFactory) {
HttpConnectionFactory connectionFactory = new HttpConnectionFactory(config);
return new SslValidatingServerConnector(server, sslContextFactory, this.ssl.getKeyAlias(),
createSslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()), connectionFactory);
}
private SslConnectionFactory createSslConnectionFactory(SslContextFactory.Server sslContextFactory,
String protocol) {
try {
return new SslConnectionFactory(sslContextFactory, protocol);
}
catch (NoSuchMethodError ex) {
// Jetty 10
try {
return SslConnectionFactory.class.getConstructor(SslContextFactory.Server.class, String.class)
.newInstance(sslContextFactory, protocol);
}
catch (Exception ex2) {
throw new RuntimeException(ex2);
}
}
}
private boolean isJettyAlpnPresent() {
return ClassUtils.isPresent("org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory", null);
}
private boolean isJettyHttp2Present() {
return ClassUtils.isPresent("org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory", null);
}
private ServerConnector createHttp2ServerConnector(Server server, HttpConfiguration config,
SslContextFactory.Server sslContextFactory) {
HttpConnectionFactory http = new HttpConnectionFactory(config);
HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(config);
ALPNServerConnectionFactory alpn = createAlpnServerConnectionFactory();
sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR);
if (isConscryptPresent()) {
sslContextFactory.setProvider("Conscrypt");
}
SslConnectionFactory ssl = createSslConnectionFactory(sslContextFactory, alpn.getProtocol());
return new SslValidatingServerConnector(server, sslContextFactory, this.ssl.getKeyAlias(), ssl, alpn, h2, http);
}
private ALPNServerConnectionFactory createAlpnServerConnectionFactory() {
try {
return new ALPNServerConnectionFactory();
}
catch (IllegalStateException ex) {
throw new IllegalStateException(
"An 'org.eclipse.jetty:jetty-alpn-*-server' dependency is required for HTTP/2 support.", ex);
}
}
private boolean isConscryptPresent() {
return ClassUtils.isPresent("org.conscrypt.Conscrypt", null)
&& ClassUtils.isPresent("org.eclipse.jetty.alpn.conscrypt.server.ConscryptServerALPNProcessor", null);
}
/**
* Configure the SSL connection.
* @param factory the Jetty {@link Server SslContextFactory.Server}.
* @param ssl the ssl details.
* @param sslStoreProvider the ssl store provider
*/
protected void configureSsl(SslContextFactory.Server factory, Ssl ssl, SslStoreProvider sslStoreProvider) {
factory.setProtocol(ssl.getProtocol());
configureSslClientAuth(factory, ssl);
configureSslPasswords(factory, ssl);
factory.setCertAlias(ssl.getKeyAlias());
if (!ObjectUtils.isEmpty(ssl.getCiphers())) {
factory.setIncludeCipherSuites(ssl.getCiphers());
factory.setExcludeCipherSuites();
}
if (ssl.getEnabledProtocols() != null) {
factory.setIncludeProtocols(ssl.getEnabledProtocols());
}
if (sslStoreProvider != null) {
try {
String keyPassword = sslStoreProvider.getKeyPassword();
if (keyPassword != null) {
factory.setKeyManagerPassword(keyPassword);
}
factory.setKeyStore(sslStoreProvider.getKeyStore());
factory.setTrustStore(sslStoreProvider.getTrustStore());
}
catch (Exception ex) {
throw new IllegalStateException("Unable to set SSL store", ex);
}
}
else {
configureSslKeyStore(factory, ssl);
configureSslTrustStore(factory, ssl);
}
}
private void configureSslClientAuth(SslContextFactory.Server factory, Ssl ssl) {
if (ssl.getClientAuth() == Ssl.ClientAuth.NEED) {
factory.setNeedClientAuth(true);
factory.setWantClientAuth(true);
}
else if (ssl.getClientAuth() == Ssl.ClientAuth.WANT) {
factory.setWantClientAuth(true);
}
}
private void configureSslPasswords(SslContextFactory.Server factory, Ssl ssl) {
if (ssl.getKeyStorePassword() != null) {
factory.setKeyStorePassword(ssl.getKeyStorePassword());
}
if (ssl.getKeyPassword() != null) {
factory.setKeyManagerPassword(ssl.getKeyPassword());
}
}
private void configureSslKeyStore(SslContextFactory.Server factory, Ssl ssl) {
try {
URL url = ResourceUtils.getURL(ssl.getKeyStore());
factory.setKeyStoreResource(Resource.newResource(url));
}
catch (Exception ex) {
throw new WebServerException("Could not load key store '" + ssl.getKeyStore() + "'", ex);
}
if (ssl.getKeyStoreType() != null) {
factory.setKeyStoreType(ssl.getKeyStoreType());
}
if (ssl.getKeyStoreProvider() != null) {
factory.setKeyStoreProvider(ssl.getKeyStoreProvider());
}
}
private void configureSslTrustStore(SslContextFactory.Server factory, Ssl ssl) {
if (ssl.getTrustStorePassword() != null) {
factory.setTrustStorePassword(ssl.getTrustStorePassword());
}
if (ssl.getTrustStore() != null) {
try {
URL url = ResourceUtils.getURL(ssl.getTrustStore());
factory.setTrustStoreResource(Resource.newResource(url));
}
catch (IOException ex) {
throw new WebServerException("Could not find trust store '" + ssl.getTrustStore() + "'", ex);
}
}
if (ssl.getTrustStoreType() != null) {
factory.setTrustStoreType(ssl.getTrustStoreType());
}
if (ssl.getTrustStoreProvider() != null) {
factory.setTrustStoreProvider(ssl.getTrustStoreProvider());
}
}
/**
* A {@link ServerConnector} that validates the ssl key alias on server startup.
*/
static class SslValidatingServerConnector extends ServerConnector {
private final SslContextFactory sslContextFactory;
private final String keyAlias;
SslValidatingServerConnector(Server server, SslContextFactory sslContextFactory, String keyAlias,
SslConnectionFactory sslConnectionFactory, HttpConnectionFactory connectionFactory) {
super(server, sslConnectionFactory, connectionFactory);
this.sslContextFactory = sslContextFactory;
this.keyAlias = keyAlias;
}
SslValidatingServerConnector(Server server, SslContextFactory sslContextFactory, String keyAlias,
ConnectionFactory... factories) {
super(server, factories);
this.sslContextFactory = sslContextFactory;
this.keyAlias = keyAlias;
}
@Override
protected void doStart() throws Exception {
super.doStart();
SslConfigurationValidator.validateKeyAlias(this.sslContextFactory.getKeyStore(), this.keyAlias);
}
}
}
相关信息
相关文章
spring ConfigurableJettyWebServerFactory 源码
spring ForwardHeadersCustomizer 源码
spring JettyEmbeddedErrorHandler 源码
spring JettyEmbeddedWebAppContext 源码
spring JettyHandlerWrappers 源码
spring JettyReactiveWebServerFactory 源码
0
赞
- 所属分类: 后端技术
- 本文标签: Spring Boot Java Spring
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦