This is an automated email from the ASF dual-hosted git repository. liyang-kylin pushed a commit to branch kylin5 in repository https://gitbox.apache.org/repos/asf/kylin.git
commit f6bb4a288e82cf301e222116b13a5b08d31b4373 Author: Li Yang <[email protected]> AuthorDate: Fri Oct 2 22:27:48 2026 +0800 KYLIN-6113 enforce authentication profile at startup --- build/sbin/bootstrap.sh | 3 +- .../apache/kylin/rest/config/SecurityConfig.java | 18 ++++++++- .../kylin/rest/config/SecurityConfigTest.java | 45 ++++++++++++++++++++++ .../config/LogoutHandlerConfiguration.java | 2 - 4 files changed, 63 insertions(+), 5 deletions(-) diff --git a/build/sbin/bootstrap.sh b/build/sbin/bootstrap.sh index 99f6490f07..3ae78d1915 100755 --- a/build/sbin/bootstrap.sh +++ b/build/sbin/bootstrap.sh @@ -441,9 +441,10 @@ function startKylin(){ checkTimeZone SERVER_MODE=$("${KYLIN_HOME}"/bin/get-properties.sh kylin.server.mode) + SECURITY_PROFILE=$("${KYLIN_HOME}"/bin/get-properties.sh kylin.security.profile) cd "${KYLIN_HOME}"/server - nohup java ${KYLIN_KERBEROS_OPTS} ${KYLIN_EXTRA_START_OPTS} ${TIME_ZONE} -Dfile.encoding=UTF-8 -Dlogging.path=${KYLIN_HOME}/logs -Dspring.profiles.active=prod -Dlogging.config=${KYLIN_SERVER_LOG4J} -Dkylin.hadoop.conf.dir=${kylin_hadoop_conf_dir} -Dhdp.version=current -Dloader.path="${kylin_hadoop_conf_dir},${KYLIN_HOME}/conf,${KYLIN_HOME}/lib/ext,${KYLIN_HOME}/server/jars,${SPARK_HOME}/jars" -XX:OnOutOfMemoryError="sh ${KYLIN_HOME}/bin/guardian.sh kill" -jar newten.jar --kylin.serv [...] + nohup java ${KYLIN_KERBEROS_OPTS} ${KYLIN_EXTRA_START_OPTS} ${TIME_ZONE} -Dfile.encoding=UTF-8 -Dlogging.path=${KYLIN_HOME}/logs -Dspring.profiles.active=prod,${SECURITY_PROFILE} -Dlogging.config=${KYLIN_SERVER_LOG4J} -Dkylin.hadoop.conf.dir=${kylin_hadoop_conf_dir} -Dhdp.version=current -Dloader.path="${kylin_hadoop_conf_dir},${KYLIN_HOME}/conf,${KYLIN_HOME}/lib/ext,${KYLIN_HOME}/server/jars,${SPARK_HOME}/jars" -XX:OnOutOfMemoryError="sh ${KYLIN_HOME}/bin/guardian.sh kill" -jar new [...] clearRedundantProcess 3 diff --git a/src/common-server/src/main/java/org/apache/kylin/rest/config/SecurityConfig.java b/src/common-server/src/main/java/org/apache/kylin/rest/config/SecurityConfig.java index 57f2048085..f265e361f8 100644 --- a/src/common-server/src/main/java/org/apache/kylin/rest/config/SecurityConfig.java +++ b/src/common-server/src/main/java/org/apache/kylin/rest/config/SecurityConfig.java @@ -22,8 +22,9 @@ import javax.servlet.Filter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; import org.springframework.core.annotation.Order; +import org.springframework.core.env.Environment; +import org.springframework.core.env.Profiles; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @@ -39,9 +40,10 @@ import lombok.extern.slf4j.Slf4j; @Order(200) @Configuration @EnableWebSecurity -@Profile({ "testing", "ldap", "custom" }) public class SecurityConfig extends WebSecurityConfigurerAdapter { + private static final String[] SUPPORTED_AUTHENTICATION_PROFILES = { "testing", "ldap", "saml", "custom" }; + @Autowired Filter fillEmptyAuthorizationFilter; @@ -51,8 +53,13 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired AuthenticationEntryPoint nUnauthorisedEntryPoint; + @Autowired + Environment environment; + @Override protected void configure(HttpSecurity http) throws Exception { + validateAuthenticationProfile(environment); + // @formatter:off // https://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/html5/#nsa-http-attributes http.formLogin() @@ -106,4 +113,11 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { http.sessionManagement(configurer -> configurer.sessionFixation().newSession()); // @formatter:on } + + static void validateAuthenticationProfile(Environment environment) { + if (!environment.acceptsProfiles(Profiles.of(SUPPORTED_AUTHENTICATION_PROFILES))) { + throw new IllegalStateException("No supported authentication profile is active. Expected one of: " + + String.join(", ", SUPPORTED_AUTHENTICATION_PROFILES)); + } + } } diff --git a/src/common-server/src/test/java/org/apache/kylin/rest/config/SecurityConfigTest.java b/src/common-server/src/test/java/org/apache/kylin/rest/config/SecurityConfigTest.java new file mode 100644 index 0000000000..9b694945d1 --- /dev/null +++ b/src/common-server/src/test/java/org/apache/kylin/rest/config/SecurityConfigTest.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.kylin.rest.config; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Profile; +import org.springframework.mock.env.MockEnvironment; + +class SecurityConfigTest { + + @Test + void testSecurityConfigIsUnconditional() { + Assertions.assertFalse(SecurityConfig.class.isAnnotationPresent(Profile.class)); + } + + @Test + void testAuthenticationProfileValidation() { + MockEnvironment environment = new MockEnvironment(); + environment.setActiveProfiles("prod"); + Assertions.assertThrows(IllegalStateException.class, + () -> SecurityConfig.validateAuthenticationProfile(environment)); + + environment.setActiveProfiles("prod", "custom"); + Assertions.assertDoesNotThrow(() -> SecurityConfig.validateAuthenticationProfile(environment)); + + environment.setActiveProfiles("prod", "saml"); + Assertions.assertDoesNotThrow(() -> SecurityConfig.validateAuthenticationProfile(environment)); + } +} diff --git a/src/common-service/src/main/java/org/apache/kylin/rest/security/config/LogoutHandlerConfiguration.java b/src/common-service/src/main/java/org/apache/kylin/rest/security/config/LogoutHandlerConfiguration.java index 0f2314d75b..97a691e308 100644 --- a/src/common-service/src/main/java/org/apache/kylin/rest/security/config/LogoutHandlerConfiguration.java +++ b/src/common-service/src/main/java/org/apache/kylin/rest/security/config/LogoutHandlerConfiguration.java @@ -23,10 +23,8 @@ import java.lang.reflect.InvocationTargetException; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; -@Profile({ "testing", "ldap", "custom" }) @Configuration public class LogoutHandlerConfiguration {
