Skip to content

Commit bbebe40

Browse files
authored
AMBARI-26296: Fix security related issues after spring upgrade (#3951)
* fix * AMBARI-26296: fix security related issues after spring upgrade
1 parent 837640d commit bbebe40

File tree

35 files changed

+358
-107
lines changed

35 files changed

+358
-107
lines changed

ambari-agent/pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,18 @@
107107
<artifactId>hadoop-common</artifactId>
108108
<version>2.7.3</version>
109109
<exclusions>
110+
<exclusion>
111+
<groupId>com.sun.jersey</groupId>
112+
<artifactId>jersey-core</artifactId>
113+
</exclusion>
114+
<exclusion>
115+
<groupId>com.sun.jersey</groupId>
116+
<artifactId>jersey-servlet</artifactId>
117+
</exclusion>
118+
<exclusion>
119+
<groupId>com.sun.jersey</groupId>
120+
<artifactId>jersey-server</artifactId>
121+
</exclusion>
110122
<exclusion>
111123
<groupId>com.jcraft</groupId>
112124
<artifactId>jsch</artifactId>

ambari-project/pom.xml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
<solr.version>5.5.2</solr.version>
3232
<ambari.dir>${project.parent.basedir}</ambari.dir>
3333
<powermock.version>2.0.9</powermock.version>
34-
<jetty.version>11.0.15</jetty.version>
34+
<jetty.version>11.0.24</jetty.version>
3535
<ldap-api.version>1.0.0</ldap-api.version>
3636
<checkstyle.version>8.9</checkstyle.version>
3737
<swagger.version>1.6.8</swagger.version>
@@ -435,11 +435,6 @@
435435
<artifactId>commons-lang</artifactId>
436436
<version>2.6</version>
437437
</dependency>
438-
<dependency>
439-
<groupId>javax.servlet</groupId>
440-
<artifactId>javax.servlet-api</artifactId>
441-
<version>3.1.0</version>
442-
</dependency>
443438
<dependency>
444439
<groupId>org.glassfish.jersey.core</groupId>
445440
<artifactId>jersey-common</artifactId>

ambari-server/pom.xml

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,14 +1169,8 @@
11691169
<dependency>
11701170
<groupId>org.eclipse.jetty</groupId>
11711171
<artifactId>jetty-jndi</artifactId>
1172-
<version>11.0.15</version>
1173-
</dependency>
1174-
<dependency>
1175-
<groupId>org.eclipse.jetty</groupId>
1176-
<artifactId>jetty-plus</artifactId>
1177-
<version>11.0.15</version>
1172+
<version>${jetty.version}</version>
11781173
</dependency>
1179-
11801174
<dependency>
11811175
<groupId>jakarta.servlet</groupId>
11821176
<artifactId>jakarta.servlet-api</artifactId>
@@ -1397,22 +1391,18 @@
13971391
<groupId>org.eclipse.jetty</groupId>
13981392
<artifactId>jetty-server</artifactId>
13991393
</dependency>
1400-
<dependency>
1401-
<groupId>org.eclipse.jetty.websocket</groupId>
1402-
<artifactId>websocket-servlet</artifactId>
1403-
</dependency>
1394+
<!-- <dependency>-->
1395+
<!-- <groupId>org.eclipse.jetty.websocket</groupId>-->
1396+
<!-- <artifactId>websocket-servlet</artifactId>-->
1397+
<!-- </dependency>-->
14041398
<dependency>
14051399
<groupId>org.eclipse.jetty.websocket</groupId>
14061400
<artifactId>websocket-jetty-server</artifactId>
14071401
<version>${jetty.version}</version>
14081402
</dependency>
1409-
<!-- <dependency>-->
1410-
<!-- <groupId>org.eclipse.jetty.websocket</groupId>-->
1411-
<!-- <artifactId>websocket-server</artifactId>-->
1412-
<!-- </dependency>-->
14131403
<dependency>
14141404
<groupId>org.eclipse.jetty.websocket</groupId>
1415-
<artifactId>websocket-jetty-server</artifactId>
1405+
<artifactId>websocket-jetty-api</artifactId>
14161406
<version>${jetty.version}</version>
14171407
</dependency>
14181408
<dependency>
@@ -1470,6 +1460,7 @@
14701460
<dependency>
14711461
<groupId>org.glassfish.jersey.core</groupId>
14721462
<artifactId>jersey-server</artifactId>
1463+
<version>${jersey.version}</version>
14731464
</dependency>
14741465
<dependency>
14751466
<groupId>org.glassfish.jersey.media</groupId>
@@ -1530,6 +1521,14 @@
15301521
<groupId>org.yaml</groupId>
15311522
<artifactId>snakeyaml</artifactId>
15321523
</exclusion>
1524+
<exclusion>
1525+
<groupId>com.sun.jersey</groupId>
1526+
<artifactId>jersey-core</artifactId>
1527+
</exclusion>
1528+
<exclusion>
1529+
<groupId>com.sun.jersey</groupId>
1530+
<artifactId>jersey-server</artifactId>
1531+
</exclusion>
15331532
</exclusions>
15341533
</dependency>
15351534
<dependency>
@@ -1649,7 +1648,7 @@
16491648
<dependency>
16501649
<groupId>cglib</groupId>
16511650
<artifactId>cglib</artifactId>
1652-
<version>3.2.4</version>
1651+
<version>3.3.0</version>
16531652
</dependency>
16541653
<dependency>
16551654
<groupId>com.google.code.gson</groupId>
@@ -1828,6 +1827,26 @@
18281827
<artifactId>hadoop-common</artifactId>
18291828
<version>${hadoop.version}</version>
18301829
<exclusions>
1830+
<exclusion>
1831+
<groupId>com.sun.jersey</groupId>
1832+
<artifactId>jersey-core</artifactId>
1833+
</exclusion>
1834+
<exclusion>
1835+
<groupId>com.sun.jersey</groupId>
1836+
<artifactId>jersey-servlet</artifactId>
1837+
</exclusion>
1838+
<exclusion>
1839+
<groupId>com.sun.jersey</groupId>
1840+
<artifactId>jersey-server</artifactId>
1841+
</exclusion>
1842+
<exclusion>
1843+
<groupId>javax.servlet</groupId>
1844+
<artifactId>javax.servlet-api</artifactId>
1845+
</exclusion>
1846+
<exclusion>
1847+
<groupId>javax.servlet.jsp</groupId>
1848+
<artifactId>jsp-api</artifactId>
1849+
</exclusion>
18311850
<exclusion>
18321851
<groupId>commons-collections</groupId>
18331852
<artifactId>commons-collections</artifactId>

ambari-server/src/main/java/org/apache/ambari/server/configuration/spring/AgentStompConfig.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ public class AgentStompConfig implements WebSocketMessageBrokerConfigurer {
5050
@Autowired
5151
private AgentRegisteringQueueChecker agentRegisteringQueueChecker;
5252

53+
54+
5355
public AgentStompConfig(ServletContext servletContext, Injector injector) {
5456
this.servletContext = servletContext;
5557
configuration = injector.getInstance(org.apache.ambari.server.configuration.Configuration.class);
@@ -79,7 +81,6 @@ public void configureClientInboundChannel(ChannelRegistration registration) {
7981
@Override
8082
public void configureClientOutboundChannel(ChannelRegistration registration) {
8183
registration.taskExecutor().corePoolSize(configuration.getSpringMessagingThreadPoolSize());
82-
// registration.setInterceptors(agentRegisteringQueueChecker);
8384
registration.interceptors(agentRegisteringQueueChecker);
8485
}
8586

ambari-server/src/main/java/org/apache/ambari/server/configuration/spring/ApiSecurityConfig.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.apache.ambari.server.security.AmbariEntryPoint;
66
import org.apache.ambari.server.security.authentication.AmbariDelegatingAuthenticationFilter;
77
import org.apache.ambari.server.security.authentication.AmbariLocalAuthenticationProvider;
8+
import org.apache.ambari.server.security.authentication.RequestBodyCachingFilter;
89
import org.apache.ambari.server.security.authentication.jwt.AmbariJwtAuthenticationProvider;
910
import org.apache.ambari.server.security.authentication.kerberos.AmbariAuthToLocalUserDetailsService;
1011
import org.apache.ambari.server.security.authentication.kerberos.AmbariKerberosAuthenticationProvider;
@@ -23,6 +24,7 @@
2324
import org.springframework.security.authentication.ProviderManager;
2425
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
2526
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
27+
import org.springframework.security.config.http.SessionCreationPolicy;
2628
import org.springframework.security.web.SecurityFilterChain;
2729
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
2830
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
@@ -42,7 +44,7 @@ public class ApiSecurityConfig {
4244
@Autowired
4345
private AmbariAuthorizationFilter authorizationFilter;
4446

45-
public ApiSecurityConfig(GuiceBeansConfig guiceBeansConfig) {
47+
public ApiSecurityConfig(GuiceBeansConfig guiceBeansConfig){
4648
this.guiceBeansConfig = guiceBeansConfig;
4749
}
4850

@@ -52,6 +54,9 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
5254
.authorizeHttpRequests(authz -> authz.anyRequest().authenticated())
5355
.headers(headers -> headers.httpStrictTransportSecurity().disable().frameOptions().disable())
5456
.exceptionHandling(exceptionHandling -> exceptionHandling.authenticationEntryPoint(ambariEntryPoint))
57+
.sessionManagement(sessionManagement -> sessionManagement
58+
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED))
59+
.addFilterBefore(new RequestBodyCachingFilter(), BasicAuthenticationFilter.class)
5560
.addFilterBefore(guiceBeansConfig.ambariUserAuthorizationFilter(), BasicAuthenticationFilter.class)
5661
.addFilterAt(delegatingAuthenticationFilter, BasicAuthenticationFilter.class)
5762
.addFilterBefore(authorizationFilter, FilterSecurityInterceptor.class);
@@ -75,7 +80,7 @@ public AuthenticationManager authenticationManager(
7580
ambariKerberosAuthenticationProvider
7681
));
7782
}
78-
83+
7984
@Bean
8085
public AmbariKerberosAuthenticationProvider ambariKerberosAuthenticationProvider(
8186
AmbariKerberosTicketValidator ambariKerberosTicketValidator,

ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariHandlerList.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@
4444
import org.apache.ambari.server.view.ViewRegistry;
4545
import org.apache.ambari.view.SystemException;
4646
import org.apache.ambari.view.ViewContext;
47-
import org.eclipse.jetty.plus.webapp.EnvConfiguration;
48-
import org.eclipse.jetty.plus.webapp.PlusConfiguration;
4947
import org.eclipse.jetty.server.Handler;
5048
import org.eclipse.jetty.server.Request;
5149
import org.eclipse.jetty.server.handler.ErrorHandler;
@@ -263,11 +261,6 @@ private WebAppContext getHandler(ViewInstanceEntity viewInstanceDefinition)
263261
webAppContext.addFilter(new FilterHolder(persistFilter), "/*", AmbariServer.DISPATCHER_TYPES);
264262
webAppContext.addFilter(new FilterHolder(springSecurityFilter), "/*", AmbariServer.DISPATCHER_TYPES);
265263
webAppContext.setAllowNullPathInfo(true);
266-
webAppContext.setConfigurations(new org.eclipse.jetty.webapp.Configuration[] {
267-
new EnvConfiguration(),
268-
new PlusConfiguration()
269-
});
270-
271264

272265
if (webAppContext.getErrorHandler() != null) {
273266
ErrorHandler errorHandlerProxy = createAmbariViewErrorHandlerProxy(webAppContext.getErrorHandler());

ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
import org.apache.ambari.server.events.AmbariPropertiesChangedEvent;
8585
import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
8686
import org.apache.ambari.server.ldap.LdapModule;
87+
import org.apache.ambari.server.listeners.WebSocketInitializerListener;
8788
import org.apache.ambari.server.metrics.system.MetricsService;
8889
import org.apache.ambari.server.orm.GuiceJpaInitializer;
8990
import org.apache.ambari.server.orm.PersistenceType;
@@ -151,6 +152,7 @@
151152
import org.eclipse.jetty.servlet.ServletHolder;
152153
import org.eclipse.jetty.util.ssl.SslContextFactory;
153154
import org.eclipse.jetty.util.thread.QueuedThreadPool;
155+
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
154156
import org.glassfish.jersey.server.ResourceConfig;
155157
import org.glassfish.jersey.servlet.ServletContainer;
156158
import org.slf4j.Logger;
@@ -389,7 +391,14 @@ public void run() throws Exception {
389391
if (configs.isAgentApiGzipped()) {
390392
configureHandlerCompression(agentroot);
391393
}
394+
395+
JettyWebSocketServletContainerInitializer initializerForAgentroot = new JettyWebSocketServletContainerInitializer((context, jettyContainer) -> {
396+
jettyContainer.setMaxTextMessageSize(configs.getStompMaxIncomingMessageSize());
397+
LOG.info("Configured WebSocket container max text message size: {}", configs.getStompMaxIncomingMessageSize());
398+
});
399+
392400
agentroot.addEventListener(new ContextLoaderListener(agentApiContext));
401+
agentroot.addEventListener(new WebSocketInitializerListener(initializerForAgentroot));
393402

394403
ServletHolder rootServlet = root.addServlet(DefaultServlet.class, "/");
395404
rootServlet.setInitParameter("dirAllowed", "false");
@@ -423,8 +432,14 @@ public void run() throws Exception {
423432
root.addFilter(new FilterHolder(new MethodOverrideFilter()), "/api/*", DISPATCHER_TYPES);
424433
root.addFilter(new FilterHolder(new ContentTypeOverrideFilter()), "/api/*", DISPATCHER_TYPES);
425434

435+
JettyWebSocketServletContainerInitializer initializerForRoot = new JettyWebSocketServletContainerInitializer((context, jettyContainer) -> {
436+
jettyContainer.setMaxTextMessageSize(configs.getStompMaxIncomingMessageSize());
437+
LOG.info("Configured WebSocket container max text message size: {}", configs.getStompMaxIncomingMessageSize());
438+
});
439+
426440
// register listener to capture request context
427441
root.addEventListener(new RequestContextListener());
442+
root.addEventListener(new WebSocketInitializerListener(initializerForRoot));
428443
root.addFilter(new FilterHolder(springSecurityFilter), "/api/*", DISPATCHER_TYPES);
429444
root.addFilter(new FilterHolder(new UserNameOverrideFilter()), "/api/v1/users/*", DISPATCHER_TYPES);
430445

@@ -623,15 +638,16 @@ private ServerConnector createSelectChannelConnectorForAgent(Server server, int
623638

624639
String srvrCrtPass = configsMap.get(Configuration.SRVR_CRT_PASS.getKey());
625640

626-
641+
SecureRequestCustomizer src = new SecureRequestCustomizer();
642+
src.setSniHostCheck(false);
643+
src.setSniRequired(false);
627644
HttpConfiguration https_config = new HttpConfiguration();
628-
https_config.addCustomizer(new SecureRequestCustomizer());
645+
https_config.addCustomizer(src);
629646
https_config.setRequestHeaderSize(configs.getHttpRequestHeaderSize());
630647
https_config.setResponseHeaderSize(configs.getHttpResponseHeaderSize());
631648
https_config.setSendServerVersion(false);
632649

633650
// Secured connector - default constructor sets trustAll = true for certs
634-
// SslContextFactory sslContextFactory = new SslContextFactory(); depricated
635651
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
636652
disableInsecureProtocols(sslContextFactory);
637653
sslContextFactory.setKeyStorePath(keystore);
@@ -642,6 +658,8 @@ private ServerConnector createSelectChannelConnectorForAgent(Server server, int
642658
sslContextFactory.setKeyStoreType(configsMap.get(Configuration.KSTR_TYPE.getKey()));
643659
sslContextFactory.setTrustStoreType(configsMap.get(Configuration.TSTR_TYPE.getKey()));
644660
sslContextFactory.setNeedClientAuth(needClientAuth);
661+
sslContextFactory.setSniRequired(false);
662+
645663
ServerConnector agentSslConnector = new ServerConnector(server, acceptors, -1,
646664
new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.toString()),
647665
new HttpConnectionFactory(https_config));
@@ -675,7 +693,10 @@ private ServerConnector createSelectChannelConnectorForClient(Server server, int
675693
String httpsCrtPass = configsMap.get(Configuration.CLIENT_API_SSL_CRT_PASS.getKey());
676694

677695
HttpConfiguration https_config = new HttpConfiguration(http_config);
678-
https_config.addCustomizer(new SecureRequestCustomizer());
696+
SecureRequestCustomizer src = new SecureRequestCustomizer();
697+
src.setSniRequired(false);
698+
src.setSniHostCheck(false);
699+
https_config.addCustomizer(src);
679700
https_config.setSecurePort(configs.getClientSSLApiPort());
680701

681702
SslContextFactory.Server contextFactoryApi = new SslContextFactory.Server();
@@ -687,6 +708,7 @@ private ServerConnector createSelectChannelConnectorForClient(Server server, int
687708
contextFactoryApi.setTrustStorePassword(httpsCrtPass);
688709
contextFactoryApi.setKeyStoreType(configsMap.get(Configuration.CLIENT_API_SSL_KSTR_TYPE.getKey()));
689710
contextFactoryApi.setTrustStoreType(configsMap.get(Configuration.CLIENT_API_SSL_KSTR_TYPE.getKey()));
711+
contextFactoryApi.setSniRequired(false);
690712
apiConnector = new ServerConnector(server, acceptors, -1,
691713
new SslConnectionFactory(contextFactoryApi, HttpVersion.HTTP_1_1.toString()),
692714
new HttpConnectionFactory(https_config));
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.ambari.server.listeners;
19+
20+
import java.util.Collections;
21+
22+
import jakarta.servlet.ServletContext;
23+
import jakarta.servlet.ServletContextEvent;
24+
import jakarta.servlet.ServletContextListener;
25+
26+
import org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer;
27+
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
28+
import org.slf4j.Logger;
29+
import org.slf4j.LoggerFactory;
30+
31+
public class WebSocketInitializerListener implements ServletContextListener {
32+
private static final Logger LOG = LoggerFactory.getLogger(WebSocketInitializerListener.class);
33+
private final JettyWebSocketServletContainerInitializer initializer;
34+
35+
public WebSocketInitializerListener(JettyWebSocketServletContainerInitializer initializer) {
36+
this.initializer = initializer;
37+
}
38+
@Override
39+
public void contextInitialized(ServletContextEvent sce) {
40+
ServletContext servletContext = sce.getServletContext();
41+
try {
42+
initializer.onStartup(Collections.emptySet(), servletContext);
43+
LOG.info("WebSocket container initialized");
44+
} catch (Exception e) {
45+
e.printStackTrace();
46+
}
47+
}
48+
49+
@Override
50+
public void contextDestroyed(ServletContextEvent sce) {
51+
ServletContext servletContext = sce.getServletContext();
52+
try {
53+
JettyWebSocketServerContainer container = (JettyWebSocketServerContainer) servletContext.getAttribute(JettyWebSocketServerContainer.class.getName());
54+
55+
if (container != null) {
56+
container.stop();
57+
LOG.info("WebSocket container stopped.");
58+
} else {
59+
LOG.info("No WebSocket container found during shutdown.");
60+
}
61+
} catch (Exception e) {
62+
e.printStackTrace();
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)