+ * 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.atlas.notification.rest; + +import org.apache.atlas.security.SecurityProperties; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.lang.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * A wrapper for getting configuration entries related to HighAvailability. + */ +public final class RestHAConfiguration { + + + public static final String ATLAS_REST_SERVER_ZK_ROOT_DEFAULT = "/apache_atlas_rest"; + + private RestHAConfiguration() { + } + + public static final String ATLAS_REST_SERVER_HA_PREFIX = "atlas.rest.server.ha."; + public static final String ZOOKEEPER_PREFIX = "zookeeper."; + public static final String ATLAS_REST_SERVER_HA_ZK_ROOT_KEY = ATLAS_REST_SERVER_HA_PREFIX + ZOOKEEPER_PREFIX + "zkroot"; + public static final String ATLAS_REST_SERVER_HA_ENABLED_KEY = ATLAS_REST_SERVER_HA_PREFIX + "enabled"; + public static final String ATLAS_REST_SERVER_ADDRESS_PREFIX = "atlas.rest.server.address."; + public static final String ATLAS_REST_SERVER_IDS = "atlas.rest.server.ids"; + public static final String HA_ZOOKEEPER_CONNECT = ATLAS_REST_SERVER_HA_PREFIX + ZOOKEEPER_PREFIX + "connect"; + public static final int DEFAULT_ZOOKEEPER_CONNECT_SLEEPTIME_MILLIS = 1000; + public static final String HA_ZOOKEEPER_RETRY_SLEEPTIME_MILLIS = + ATLAS_REST_SERVER_HA_PREFIX + ZOOKEEPER_PREFIX + "retry.sleeptime.ms"; + public static final String HA_ZOOKEEPER_NUM_RETRIES = ATLAS_REST_SERVER_HA_PREFIX + ZOOKEEPER_PREFIX + "num.retries"; + public static final int DEFAULT_ZOOKEEPER_CONNECT_NUM_RETRIES = 3; + public static final String HA_ZOOKEEPER_SESSION_TIMEOUT_MS = + ATLAS_REST_SERVER_HA_PREFIX + ZOOKEEPER_PREFIX + "session.timeout.ms"; + public static final int DEFAULT_ZOOKEEPER_SESSION_TIMEOUT_MILLIS = 20000; + public static final String HA_ZOOKEEPER_ACL = ATLAS_REST_SERVER_HA_PREFIX + ZOOKEEPER_PREFIX + "acl"; + public static final String HA_ZOOKEEPER_AUTH = ATLAS_REST_SERVER_HA_PREFIX + ZOOKEEPER_PREFIX + "auth"; + + /** + * Return whether HA is enabled or not. + * + * @param configuration underlying configuration instance + * @return + */ + public static boolean isHAEnabled(Configuration configuration) { + boolean ret = false; + + if (configuration.containsKey(RestHAConfiguration.ATLAS_REST_SERVER_HA_ENABLED_KEY)) { + ret = configuration.getBoolean(ATLAS_REST_SERVER_HA_ENABLED_KEY); + } else { + String[] ids = configuration.getStringArray(RestHAConfiguration.ATLAS_REST_SERVER_IDS); + + ret = ids != null && ids.length > 1; + } + + return ret; + } + + /** + * Get the web server address that a server instance with the passed ID is bound to. + *
+ * This method uses the property {@link SecurityProperties#TLS_ENABLED} to determine whether
+ * the URL is http or https.
+ *
+ * @param configuration underlying configuration
+ * @param serverId serverId whose host:port property is picked to build the web server address.
+ * @return
+ */
+ public static String getBoundAddressForId(Configuration configuration, String serverId) {
+ String hostPort = configuration.getString(ATLAS_REST_SERVER_ADDRESS_PREFIX + serverId);
+ boolean isSecure = configuration.getBoolean(SecurityProperties.TLS_ENABLED);
+ String protocol = (isSecure) ? "https://" : "http://";
+ return protocol + hostPort;
+ }
+
+ public static List
+ * 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.atlas.notification.rest;
+
+import org.apache.atlas.ApplicationProperties;
+import org.apache.atlas.AtlasConstants;
+import org.apache.atlas.server.common.service.EmbeddedServer;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.bridge.SLF4JBridgeHandler;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Iterator;
+
+public class RestNotificationMain {
+ private static final Logger LOG = LoggerFactory.getLogger(RestNotificationMain.class);
+ private static final String APP_PATH = "app";
+ private static final String APP_PORT = "port";
+ private static final String REST_NOTIFICATION_HOME = "atlas.rest.notification.home";
+ private static final String REST_NOTIFICATION_DATA = "atlas.rest.notification.data";
+ private static final String REST_NOTIFICATION_LOG_DIR = "atlas.rest.notification.log.dir";
+ private static final String REST_SERVER_HTTPS_PORT = "atlas.rest.server.https.port";
+ private static final String REST_SERVER_HTTP_PORT = "atlas.rest.server.http.port";
+
+ private static EmbeddedServer server;
+
+ /**
+ * Prevent users from constructing this.
+ */
+ private RestNotificationMain() {
+ }
+
+ protected static CommandLine parseArgs(String[] args) throws ParseException {
+ Options options = new Options();
+ Option opt;
+
+ opt = new Option(APP_PATH, true, "Application Path");
+ opt.setRequired(false);
+ options.addOption(opt);
+
+ opt = new Option(APP_PORT, true, "Application Port");
+ opt.setRequired(false);
+ options.addOption(opt);
+
+ return new DefaultParser().parse(options, args);
+ }
+
+ public static void main(String[] args) throws Exception {
+ CommandLine cmd = parseArgs(args);
+ PropertiesConfiguration buildConfiguration = new PropertiesConfiguration("rest-notification-buildinfo.properties");
+ String appPath = "rest-notification-webapp/target/rest-notification-webapp" /*\\+ getProjectVersion(buildConfiguration)*/;
+
+ if (cmd.hasOption(APP_PATH)) {
+ appPath = cmd.getOptionValue(APP_PATH);
+ }
+
+ setApplicationHome();
+ Configuration configuration = ApplicationProperties.get();
+ final String enableTLSFlag = configuration.getString(SecurityProperties.TLS_ENABLED);
+ final String appHost = configuration.getString(SecurityProperties.BIND_ADDRESS, EmbeddedServer.REST_DEFAULT_BIND_ADDRESS);
+
+ if (!isLocalAddress(InetAddress.getByName(appHost))) {
+ String msg =
+ "Failed to start Rest Notification server. Address " + appHost
+ + " does not belong to this host. Correct configuration parameter: "
+ + SecurityProperties.BIND_ADDRESS;
+ LOG.error(msg);
+ throw new IOException(msg);
+ }
+
+ final int appPort = getApplicationPort(cmd, enableTLSFlag, configuration);
+ System.setProperty(AtlasConstants.SYSTEM_PROPERTY_APP_PORT, String.valueOf(appPort));
+ final boolean enableTLS = isTLSEnabled(enableTLSFlag, appPort);
+ configuration.setProperty(SecurityProperties.TLS_ENABLED, String.valueOf(enableTLS));
+
+ showStartupInfo(buildConfiguration, enableTLS, appPort);
+
+ server = EmbeddedServer.newServer(appHost, appPort, appPath, enableTLS);
+ installLogBridge();
+
+ server.start();
+ }
+
+ public static String getProjectVersion(PropertiesConfiguration buildConfiguration) {
+ return buildConfiguration.getString("project.version");
+ }
+
+ private static void setApplicationHome() {
+ if (System.getProperty(REST_NOTIFICATION_HOME) == null) {
+ System.setProperty(REST_NOTIFICATION_HOME, "target");
+ }
+ if (System.getProperty(REST_NOTIFICATION_DATA) == null) {
+ System.setProperty(REST_NOTIFICATION_DATA, "target/data");
+ }
+ if (System.getProperty(REST_NOTIFICATION_LOG_DIR) == null) {
+ System.setProperty(REST_NOTIFICATION_LOG_DIR, "target/logs");
+ }
+ }
+
+ private static boolean isLocalAddress(InetAddress addr) {
+ // Check if the address is any local or loop back
+ boolean local = addr.isAnyLocalAddress() || addr.isLoopbackAddress();
+
+ // Check if the address is defined on any interface
+ if (!local) {
+ try {
+ local = NetworkInterface.getByInetAddress(addr) != null;
+ } catch (SocketException e) {
+ local = false;
+ }
+ }
+ return local;
+ }
+
+
+ static int getApplicationPort(CommandLine cmd, String enableTLSFlag, Configuration configuration) {
+ String optionValue = cmd.hasOption(APP_PORT) ? cmd.getOptionValue(APP_PORT) : null;
+
+ final int appPort;
+
+ if (StringUtils.isNotEmpty(optionValue)) {
+ appPort = Integer.valueOf(optionValue);
+ } else {
+ // default : atlas.enableTLS is true
+ appPort = getPortValue(configuration, enableTLSFlag);
+ }
+
+ return appPort;
+ }
+
+
+ private static int getPortValue(Configuration configuration, String enableTLSFlag) {
+ int appPort;
+
+ assert configuration != null;
+ appPort = StringUtils.isEmpty(enableTLSFlag) || enableTLSFlag.equals("true") ?
+ configuration.getInt(REST_SERVER_HTTPS_PORT, 41443) :
+ configuration.getInt(REST_SERVER_HTTP_PORT, 41000);
+ return appPort;
+ }
+
+ private static boolean isTLSEnabled(String enableTLSFlag, int appPort) {
+ return Boolean.valueOf(StringUtils.isEmpty(enableTLSFlag) ?
+ System.getProperty(org.apache.atlas.security.SecurityProperties.TLS_ENABLED, (appPort % 1000) == 443 ? "true" : "false") : enableTLSFlag);
+ }
+
+
+ private static void showStartupInfo(PropertiesConfiguration buildConfiguration, boolean enableTLS, int appPort) {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append("\n############################################");
+ buffer.append("############################################");
+ buffer.append("\n Rest Notification Server (STARTUP)");
+ buffer.append("\n");
+ try {
+ final Iterator
+ * 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.atlas.notification.rest.ha;
+
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.notification.rest.AtlasServerIdSelector;
+import org.apache.atlas.notification.rest.RestHAConfiguration;
+import org.apache.atlas.server.common.service.HighAvailabilityProperties;
+import org.apache.atlas.server.common.service.HighAvailabilitySupport;
+import org.apache.commons.configuration.Configuration;
+import org.springframework.stereotype.Component;
+
+/**
+ * Rest notification implementation of {@link HighAvailabilitySupport} using {@link RestHAConfiguration}.
+ */
+@Component
+public class RestNotificationHighAvailabilitySupport implements HighAvailabilitySupport {
+ @Override
+ public boolean isHAEnabled(Configuration configuration) {
+ return RestHAConfiguration.isHAEnabled(configuration);
+ }
+
+ @Override
+ public String selectServerId(Configuration configuration) throws AtlasException {
+ return AtlasServerIdSelector.selectServerId(configuration);
+ }
+
+ @Override
+ public String getBoundAddressForId(Configuration configuration, String serverId) {
+ return RestHAConfiguration.getBoundAddressForId(configuration, serverId);
+ }
+
+ @Override
+ public HighAvailabilityProperties getZookeeperProperties(Configuration configuration) {
+ RestHAConfiguration.ZookeeperProperties props = RestHAConfiguration.getZookeeperProperties(configuration);
+
+ return new HighAvailabilityProperties(
+ props.getConnectString(),
+ props.getZkRoot(),
+ props.getRetriesSleepTimeMillis(),
+ props.getNumRetries(),
+ props.getSessionTimeout(),
+ props.getAcl(),
+ props.getAuth());
+ }
+}
diff --git a/rest-notification-webapp/src/main/java/org/apache/atlas/notification/rest/util/CredentialProviderUtility.java b/rest-notification-webapp/src/main/java/org/apache/atlas/notification/rest/util/CredentialProviderUtility.java
new file mode 100755
index 0000000000..d50368cfa5
--- /dev/null
+++ b/rest-notification-webapp/src/main/java/org/apache/atlas/notification/rest/util/CredentialProviderUtility.java
@@ -0,0 +1,227 @@
+/*
+ * 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.atlas.notification.rest.util;
+
+import org.apache.atlas.server.common.dao.UserDao;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.Options;
+import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.alias.CredentialProvider;
+import org.apache.hadoop.security.alias.CredentialProviderFactory;
+
+import java.io.Console;
+import java.io.IOException;
+import java.util.Arrays;
+
+
+import static org.apache.atlas.notification.rest.SecurityProperties.KEYSTORE_PASSWORD_KEY;
+import static org.apache.atlas.notification.rest.SecurityProperties.SERVER_CERT_PASSWORD_KEY;
+import static org.apache.atlas.notification.rest.SecurityProperties.TRUSTSTORE_PASSWORD_KEY;
+/**
+ * A utility class for generating a credential provider containing the entries required for supporting the SSL
+ * implementation
+ * of the DGC server.
+ */
+public class CredentialProviderUtility {
+ private static final String[] KEYS = new String[] { KEYSTORE_PASSWORD_KEY, TRUSTSTORE_PASSWORD_KEY, SERVER_CERT_PASSWORD_KEY };
+ public static abstract class TextDevice {
+ public abstract void printf(String fmt, Object... params);
+
+ public abstract String readLine(String fmt, Object... args);
+
+ public abstract char[] readPassword(String fmt, Object... args);
+
+ }
+
+ private static TextDevice DEFAULT_TEXT_DEVICE = new TextDevice() {
+ Console console = System.console();
+
+ @Override
+ public void printf(String fmt, Object... params) {
+ console.printf(fmt, params);
+ }
+
+ @Override
+ public String readLine(String fmt, Object... args) {
+ return console.readLine(fmt, args);
+ }
+
+ @Override
+ public char[] readPassword(String fmt, Object... args) {
+ return console.readPassword(fmt, args);
+ }
+ };
+
+ public static TextDevice textDevice = DEFAULT_TEXT_DEVICE;
+
+ public static void main(String[] args) throws IOException {
+ try {
+ CommandLine cmd = new DefaultParser().parse(createOptions(), args);
+ boolean generatePasswordOption = cmd.hasOption("g");
+ String key = cmd.getOptionValue("k");
+ char[] cred = null;
+ String providerPath = cmd.getOptionValue("f");
+
+ if (cmd.hasOption("p")) {
+ cred = cmd.getOptionValue("p").toCharArray();
+ }
+
+ if (generatePasswordOption) {
+ String userName = cmd.getOptionValue("u");
+ String password = cmd.getOptionValue("p");
+ if (userName != null && password != null) {
+ String encryptedPassword = UserDao.encrypt(password);
+ boolean silentOption = cmd.hasOption("s");
+
+ if (silentOption) {
+ System.out.println(encryptedPassword);
+ } else {
+ System.out.println("Your encrypted password is : " + encryptedPassword);
+ }
+ } else {
+ System.out.println("Please provide username and password as input. Usage: cputil.py -g -u
+ * 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.atlas.notification.rest.web.resources;
+
+import org.apache.atlas.ApplicationProperties;
+import org.apache.atlas.AtlasClient;
+import org.apache.atlas.server.common.util.Servlets;
+import org.apache.atlas.server.common.service.ServiceState;
+import org.apache.atlas.utils.AtlasJson;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.stereotype.Service;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Jersey Resource for admin operations.
+ */
+@Path("api/atlas/admin")
+@Singleton
+@Service
+@EnableScheduling
+public class AdminResource {
+ private static final Logger LOG = LoggerFactory.getLogger(AdminResource.class);
+
+
+ private static Configuration atlasProperties;
+ private final ServiceState serviceState;
+
+ static {
+ try {
+ atlasProperties = ApplicationProperties.get();
+ } catch (Exception e) {
+ LOG.info("Failed to load application properties", e);
+ }
+ }
+
+ @Inject
+ public AdminResource(ServiceState serviceState) {
+ this.serviceState = serviceState;
+ }
+
+ /**
+ * Fetches the thread stack dump for this application.
+ *
+ * @return json representing the thread stack dump.
+ */
+ @GET
+ @Path("stack")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String getThreadDump() {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> AdminResource.getThreadDump()");
+ }
+
+ ThreadGroup topThreadGroup = Thread.currentThread().getThreadGroup();
+
+ while (topThreadGroup.getParent() != null) {
+ topThreadGroup = topThreadGroup.getParent();
+ }
+ Thread[] threads = new Thread[topThreadGroup.activeCount()];
+
+ int nr = topThreadGroup.enumerate(threads);
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < nr; i++) {
+ builder.append(threads[i].getName()).append("\nState: ").
+ append(threads[i].getState()).append("\n");
+ String stackTrace = StringUtils.join(threads[i].getStackTrace(), "\n");
+ builder.append(stackTrace);
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== AdminResource.getThreadDump()");
+ }
+
+ return builder.toString();
+ }
+
+
+ @GET
+ @Path("status")
+ @Produces(Servlets.JSON_MEDIA_TYPE)
+ public Response getStatus() {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> AdminResource.getStatus()");
+ }
+
+ Map
+ * 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.atlas.notification.rest.web.security;
+
+import org.apache.atlas.server.common.filters.ActiveServerFilter;
+import org.apache.atlas.server.common.filters.AtlasAuthenticationEntryPoint;
+import org.apache.atlas.server.common.filters.AtlasAuthenticationFilter;
+import org.apache.atlas.server.common.filters.AtlasCSRFPreventionFilter;
+import org.apache.atlas.server.common.filters.AtlasDelegatingAuthenticationEntryPoint;
+import org.apache.atlas.server.common.filters.AtlasKnoxSSOAuthenticationFilter;
+import org.apache.atlas.server.common.filters.HeadersUtil;
+import org.apache.atlas.server.common.filters.spi.ActiveInstanceStateProvider;
+import org.apache.atlas.server.common.filters.spi.AtlasAuthenticationProviderBridge;
+import org.apache.atlas.server.common.filters.spi.ServiceStateProvider;
+import org.apache.atlas.server.common.security.AtlasAuthenticationProvider;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint;
+import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
+import org.springframework.security.web.header.writers.StaticHeadersWriter;
+import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
+import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;
+import org.springframework.security.web.util.matcher.RequestMatcher;
+
+import javax.inject.Inject;
+import java.util.LinkedHashMap;
+
+import org.apache.atlas.server.common.security.AtlasAuthenticationFailureHandler;
+import org.apache.atlas.server.common.security.AtlasAuthenticationSuccessHandler;
+
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter {
+ private static final Logger LOG = LoggerFactory.getLogger(AtlasSecurityConfig.class);
+
+ private final AtlasAuthenticationProvider authenticationProvider;
+ private final AtlasAuthenticationSuccessHandler successHandler;
+ private final AtlasAuthenticationFailureHandler failureHandler;
+ private final AtlasKnoxSSOAuthenticationFilter ssoAuthenticationFilter;
+ private final AtlasAuthenticationFilter atlasAuthenticationFilter;
+ private final AtlasCSRFPreventionFilter csrfPreventionFilter;
+ private final AtlasAuthenticationEntryPoint atlasAuthenticationEntryPoint;
+
+ // Our own Atlas filters need to be registered as well
+ private final Configuration configuration;
+ private final ActiveServerFilter activeServerFilter;
+
+ @Inject
+ public AtlasSecurityConfig(AtlasKnoxSSOAuthenticationFilter ssoAuthenticationFilter,
+ AtlasCSRFPreventionFilter atlasCSRFPreventionFilter,
+ AtlasAuthenticationFilter atlasAuthenticationFilter,
+ AtlasAuthenticationProvider authenticationProvider,
+ AtlasAuthenticationSuccessHandler successHandler,
+ AtlasAuthenticationFailureHandler failureHandler,
+ AtlasAuthenticationEntryPoint atlasAuthenticationEntryPoint,
+ Configuration configuration,
+ ActiveServerFilter activeServerFilter)
+
+ {
+ this.ssoAuthenticationFilter = ssoAuthenticationFilter;
+ this.csrfPreventionFilter = atlasCSRFPreventionFilter;
+ this.atlasAuthenticationFilter = atlasAuthenticationFilter;
+ this.authenticationProvider = authenticationProvider;
+ this.successHandler = successHandler;
+ this.failureHandler = failureHandler;
+ this.atlasAuthenticationEntryPoint = atlasAuthenticationEntryPoint;
+ this.configuration = configuration;
+ this.activeServerFilter = activeServerFilter;
+ }
+
+ public AuthenticationEntryPoint getAuthenticationEntryPoint() {
+ LinkedHashMap
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * 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.
@@ -12,7 +12,7 @@
* limitations under the License. See accompanying LICENSE file.
*/
-package org.apache.atlas.web.filters;
+package org.apache.atlas.server.common.filters;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
@@ -20,217 +20,309 @@
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.SessionCookieConfig;
import javax.servlet.SessionTrackingMode;
import javax.servlet.descriptor.JspConfigDescriptor;
-
import java.io.InputStream;
+import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.Map;
import java.util.Set;
+
/**
*/
public class NullServletContext implements ServletContext {
- public String getContextPath() {
- return null;
+
+
+
+ public void setSessionTrackingModes(
+ Set
+ * 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.atlas.server.common.filters.spi;
+
+public interface ActiveInstanceStateProvider {
+ String getActiveServerAddress();
+}
diff --git a/server-common/src/main/java/org/apache/atlas/server/common/filters/spi/AtlasAuthenticationProviderBridge.java b/server-common/src/main/java/org/apache/atlas/server/common/filters/spi/AtlasAuthenticationProviderBridge.java
new file mode 100644
index 0000000000..6ef3361cbf
--- /dev/null
+++ b/server-common/src/main/java/org/apache/atlas/server/common/filters/spi/AtlasAuthenticationProviderBridge.java
@@ -0,0 +1,34 @@
+/**
+ * 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.atlas.server.common.filters.spi;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+
+import java.util.List;
+
+public interface AtlasAuthenticationProviderBridge {
+ List
+ * 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.atlas.server.common.filters.spi;
+
+public interface ServiceStateProvider {
+ boolean isActive();
+
+ boolean isInstanceInTransition();
+
+ boolean isInstanceInMigration();
+
+ String getStateName();
+}
diff --git a/webapp/src/main/java/org/apache/atlas/web/listeners/LoginProcessor.java b/server-common/src/main/java/org/apache/atlas/server/common/listeners/LoginProcessor.java
similarity index 99%
rename from webapp/src/main/java/org/apache/atlas/web/listeners/LoginProcessor.java
rename to server-common/src/main/java/org/apache/atlas/server/common/listeners/LoginProcessor.java
index e8a198e339..066da4329f 100644
--- a/webapp/src/main/java/org/apache/atlas/web/listeners/LoginProcessor.java
+++ b/server-common/src/main/java/org/apache/atlas/server/common/listeners/LoginProcessor.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.atlas.web.listeners;
+package org.apache.atlas.server.common.listeners;
import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasException;
diff --git a/webapp/src/main/java/org/apache/atlas/web/model/User.java b/server-common/src/main/java/org/apache/atlas/server/common/model/User.java
similarity index 98%
rename from webapp/src/main/java/org/apache/atlas/web/model/User.java
rename to server-common/src/main/java/org/apache/atlas/server/common/model/User.java
index c7bbdceb00..be664b62e1 100644
--- a/webapp/src/main/java/org/apache/atlas/web/model/User.java
+++ b/server-common/src/main/java/org/apache/atlas/server/common/model/User.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.atlas.web.model;
+package org.apache.atlas.server.common.model;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
diff --git a/webapp/src/main/java/org/apache/atlas/web/security/AtlasADAuthenticationProvider.java b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasADAuthenticationProvider.java
similarity index 98%
rename from webapp/src/main/java/org/apache/atlas/web/security/AtlasADAuthenticationProvider.java
rename to server-common/src/main/java/org/apache/atlas/server/common/security/AtlasADAuthenticationProvider.java
index 59329a0643..3c57b8dd73 100644
--- a/webapp/src/main/java/org/apache/atlas/web/security/AtlasADAuthenticationProvider.java
+++ b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasADAuthenticationProvider.java
@@ -16,10 +16,10 @@
* limitations under the License.
*/
-package org.apache.atlas.web.security;
+package org.apache.atlas.server.common.security;
import org.apache.atlas.ApplicationProperties;
-import org.apache.atlas.web.model.User;
+import org.apache.atlas.server.common.model.User;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationConverter;
import org.slf4j.Logger;
@@ -41,6 +41,8 @@
import java.util.List;
import java.util.Properties;
+import org.apache.atlas.server.common.security.AtlasAuthenticationException;
+
@Component
public class AtlasADAuthenticationProvider extends AtlasAbstractAuthenticationProvider {
private static final Logger LOG = LoggerFactory.getLogger(AtlasADAuthenticationProvider.class);
diff --git a/webapp/src/main/java/org/apache/atlas/web/security/AtlasAbstractAuthenticationProvider.java b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasAbstractAuthenticationProvider.java
similarity index 98%
rename from webapp/src/main/java/org/apache/atlas/web/security/AtlasAbstractAuthenticationProvider.java
rename to server-common/src/main/java/org/apache/atlas/server/common/security/AtlasAbstractAuthenticationProvider.java
index cc2d1587c1..7c3014d4e4 100644
--- a/webapp/src/main/java/org/apache/atlas/web/security/AtlasAbstractAuthenticationProvider.java
+++ b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasAbstractAuthenticationProvider.java
@@ -17,8 +17,9 @@
* under the License.
*/
-package org.apache.atlas.web.security;
+package org.apache.atlas.server.common.security;
+import org.apache.atlas.server.common.model.User;
import org.apache.atlas.utils.AuthenticationUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.hadoop.conf.Configuration;
@@ -31,7 +32,6 @@
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.ArrayList;
diff --git a/webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationException.java b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasAuthenticationException.java
similarity index 95%
rename from webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationException.java
rename to server-common/src/main/java/org/apache/atlas/server/common/security/AtlasAuthenticationException.java
index cda9fad622..34be0fb46f 100644
--- a/webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationException.java
+++ b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasAuthenticationException.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.atlas.web.security;
+package org.apache.atlas.server.common.security;
import org.springframework.security.core.AuthenticationException;
diff --git a/webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationFailureHandler.java b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasAuthenticationFailureHandler.java
similarity index 93%
rename from webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationFailureHandler.java
rename to server-common/src/main/java/org/apache/atlas/server/common/security/AtlasAuthenticationFailureHandler.java
index 514ccbc4db..452b254869 100644
--- a/webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationFailureHandler.java
+++ b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasAuthenticationFailureHandler.java
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-package org.apache.atlas.web.security;
+package org.apache.atlas.server.common.security;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
@@ -25,6 +25,7 @@
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
+import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -35,7 +36,7 @@ public class AtlasAuthenticationFailureHandler implements AuthenticationFailureH
private static final Logger LOG = LoggerFactory.getLogger(AtlasAuthenticationFailureHandler.class);
@Override
- public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse response, AuthenticationException e) throws IOException {
+ public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
LOG.debug("Login Failure ", e);
JSONObject json = new JSONObject();
diff --git a/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasAuthenticationProvider.java b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasAuthenticationProvider.java
new file mode 100644
index 0000000000..3878ad26f8
--- /dev/null
+++ b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasAuthenticationProvider.java
@@ -0,0 +1,164 @@
+/**
+ * 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.atlas.server.common.security;
+
+import org.apache.atlas.ApplicationProperties;
+import org.apache.commons.configuration.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Scope;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+@Component("atlasServerCommonAuthenticationProvider")
+@Scope("prototype")
+public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProvider {
+ private static final Logger LOG = LoggerFactory
+ .getLogger(AtlasAuthenticationProvider.class);
+
+ private boolean fileAuthenticationMethodEnabled = true;
+ private boolean pamAuthenticationEnabled = false;
+ private String ldapType = "NONE";
+ public static final String FILE_AUTH_METHOD = "atlas.authentication.method.file";
+ public static final String LDAP_AUTH_METHOD = "atlas.authentication.method.ldap";
+ public static final String LDAP_TYPE = "atlas.authentication.method.ldap.type";
+ public static final String PAM_AUTH_METHOD = "atlas.authentication.method.pam";
+
+
+
+ private boolean ssoEnabled;
+
+ final AtlasLdapAuthenticationProvider ldapAuthenticationProvider;
+
+ final AtlasFileAuthenticationProvider fileAuthenticationProvider;
+
+ final AtlasADAuthenticationProvider adAuthenticationProvider;
+
+ final AtlasPamAuthenticationProvider pamAuthenticationProvider;
+
+ @Inject
+ public AtlasAuthenticationProvider(AtlasLdapAuthenticationProvider ldapAuthenticationProvider,
+ AtlasFileAuthenticationProvider fileAuthenticationProvider,
+ AtlasADAuthenticationProvider adAuthenticationProvider,
+ AtlasPamAuthenticationProvider pamAuthenticationProvider) {
+ this.ldapAuthenticationProvider = ldapAuthenticationProvider;
+ this.fileAuthenticationProvider = fileAuthenticationProvider;
+ this.adAuthenticationProvider = adAuthenticationProvider;
+ this.pamAuthenticationProvider = pamAuthenticationProvider;
+ }
+
+ @PostConstruct
+ void setAuthenticationMethod() {
+ try {
+ Configuration configuration = ApplicationProperties.get();
+
+ this.fileAuthenticationMethodEnabled = configuration.getBoolean(FILE_AUTH_METHOD, true);
+
+ this.pamAuthenticationEnabled = configuration.getBoolean(PAM_AUTH_METHOD, false);
+
+ boolean ldapAuthenticationEnabled = configuration.getBoolean(LDAP_AUTH_METHOD, false);
+
+ if (ldapAuthenticationEnabled) {
+ this.ldapType = configuration.getString(LDAP_TYPE, "NONE");
+ } else {
+ this.ldapType = "NONE";
+ }
+ } catch (Exception e) {
+ LOG.error("Error while getting atlas.login.method application properties", e);
+ }
+ }
+
+ @Override
+ public Authentication authenticate(Authentication authentication)
+ throws AuthenticationException {
+
+ if(ssoEnabled){
+ if (authentication != null){
+ authentication = getSSOAuthentication(authentication);
+ if(authentication!=null && authentication.isAuthenticated()){
+ return authentication;
+ }
+ }
+ } else {
+
+ if (ldapType.equalsIgnoreCase("LDAP")) {
+ try {
+ authentication = ldapAuthenticationProvider.authenticate(authentication);
+ } catch (Exception ex) {
+ LOG.error("Error while LDAP authentication", ex);
+ }
+ } else if (ldapType.equalsIgnoreCase("AD")) {
+ try {
+ authentication = adAuthenticationProvider.authenticate(authentication);
+ } catch (Exception ex) {
+ LOG.error("Error while AD authentication", ex);
+ }
+ } else if (pamAuthenticationEnabled) {
+ try {
+ authentication = pamAuthenticationProvider.authenticate(authentication);
+ } catch (Exception ex) {
+ LOG.error("Error while PAM authentication", ex);
+ }
+ }
+ }
+
+ if (authentication != null) {
+ if (authentication.isAuthenticated()) {
+ return authentication;
+ } else if (fileAuthenticationMethodEnabled) { // If the LDAP/AD/PAM authentication fails try the local filebased login method
+ authentication = fileAuthenticationProvider.authenticate(authentication);
+
+ if (authentication != null && authentication.isAuthenticated()) {
+ return authentication;
+ }
+ }
+ }
+
+ LOG.error("Authentication failed.");
+ throw new AtlasAuthenticationException("Authentication failed.");
+ }
+
+ @Override
+ public boolean supports(Class> authentication) {
+ if (pamAuthenticationEnabled) {
+ return pamAuthenticationProvider.supports(authentication);
+ } else if (ldapType.equalsIgnoreCase("LDAP")) {
+ return ldapAuthenticationProvider.supports(authentication);
+ } else if (ldapType.equalsIgnoreCase("AD")) {
+ return adAuthenticationProvider.supports(authentication);
+ } else {
+ return super.supports(authentication);
+ }
+ }
+
+ public boolean isSsoEnabled() {
+ return ssoEnabled;
+ }
+
+ public void setSsoEnabled(boolean ssoEnabled) {
+ this.ssoEnabled = ssoEnabled;
+ }
+
+ private Authentication getSSOAuthentication(Authentication authentication) throws AuthenticationException{
+ return authentication;
+ }
+}
diff --git a/webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationSuccessHandler.java b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasAuthenticationSuccessHandler.java
similarity index 81%
rename from webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationSuccessHandler.java
rename to server-common/src/main/java/org/apache/atlas/server/common/security/AtlasAuthenticationSuccessHandler.java
index 5d6834fd19..c73a09e130 100644
--- a/webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationSuccessHandler.java
+++ b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasAuthenticationSuccessHandler.java
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-package org.apache.atlas.web.security;
+package org.apache.atlas.server.common.security;
import org.apache.atlas.AtlasConfiguration;
import org.json.simple.JSONObject;
@@ -27,18 +27,18 @@
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
+import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-
import java.io.IOException;
+
@Component
public class AtlasAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
- private static final Logger LOG = LoggerFactory.getLogger(AtlasAuthenticationSuccessHandler.class);
-
- public static final String LOCALLOGIN = "locallogin";
+ private static Logger LOG = LoggerFactory.getLogger(AuthenticationSuccessHandler.class);
private int sessionTimeout = 3600;
+ public static final String LOCALLOGIN = "locallogin";
@PostConstruct
public void setup() {
@@ -46,22 +46,22 @@ public void setup() {
}
@Override
- public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
- LOG.debug("Login Success {}", authentication.getPrincipal());
+ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
+ Authentication authentication) throws IOException, ServletException {
- JSONObject json = new JSONObject();
+ LOG.debug("Login Success " + authentication.getPrincipal());
+ JSONObject json = new JSONObject();
json.put("msgDesc", "Success");
if (request.getSession() != null) { // incase of form based login mark it as local login in session
- request.getSession().setAttribute(LOCALLOGIN, "true");
+ request.getSession().setAttribute(LOCALLOGIN,"true");
request.getServletContext().setAttribute(request.getSession().getId(), LOCALLOGIN);
if (this.sessionTimeout != -1) {
request.getSession().setMaxInactiveInterval(sessionTimeout);
}
}
-
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_OK);
response.setCharacterEncoding("UTF-8");
diff --git a/webapp/src/main/java/org/apache/atlas/web/security/AtlasFileAuthenticationProvider.java b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasFileAuthenticationProvider.java
similarity index 96%
rename from webapp/src/main/java/org/apache/atlas/web/security/AtlasFileAuthenticationProvider.java
rename to server-common/src/main/java/org/apache/atlas/server/common/security/AtlasFileAuthenticationProvider.java
index 096ca26d83..bda282009a 100644
--- a/webapp/src/main/java/org/apache/atlas/web/security/AtlasFileAuthenticationProvider.java
+++ b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasFileAuthenticationProvider.java
@@ -14,9 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.atlas.web.security;
+package org.apache.atlas.server.common.security;
-import org.apache.atlas.web.dao.UserDao;
+import org.apache.atlas.server.common.dao.UserDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.BadCredentialsException;
diff --git a/webapp/src/main/java/org/apache/atlas/web/security/AtlasLdapAuthenticationProvider.java b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasLdapAuthenticationProvider.java
similarity index 98%
rename from webapp/src/main/java/org/apache/atlas/web/security/AtlasLdapAuthenticationProvider.java
rename to server-common/src/main/java/org/apache/atlas/server/common/security/AtlasLdapAuthenticationProvider.java
index c401576006..057f764fed 100644
--- a/webapp/src/main/java/org/apache/atlas/web/security/AtlasLdapAuthenticationProvider.java
+++ b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasLdapAuthenticationProvider.java
@@ -16,10 +16,10 @@
* limitations under the License.
*/
-package org.apache.atlas.web.security;
+package org.apache.atlas.server.common.security;
import org.apache.atlas.ApplicationProperties;
-import org.apache.atlas.web.model.User;
+import org.apache.atlas.server.common.model.User;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationConverter;
import org.apache.commons.lang3.StringUtils;
@@ -43,6 +43,8 @@
import java.util.List;
import java.util.Properties;
+import org.apache.atlas.server.common.security.AtlasAuthenticationException;
+
@Component
public class AtlasLdapAuthenticationProvider extends AtlasAbstractAuthenticationProvider {
private static final Logger LOG = LoggerFactory.getLogger(AtlasLdapAuthenticationProvider.class);
diff --git a/webapp/src/main/java/org/apache/atlas/web/security/AtlasPamAuthenticationProvider.java b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasPamAuthenticationProvider.java
similarity index 95%
rename from webapp/src/main/java/org/apache/atlas/web/security/AtlasPamAuthenticationProvider.java
rename to server-common/src/main/java/org/apache/atlas/server/common/security/AtlasPamAuthenticationProvider.java
index 49970129c3..fac38d30cc 100644
--- a/webapp/src/main/java/org/apache/atlas/web/security/AtlasPamAuthenticationProvider.java
+++ b/server-common/src/main/java/org/apache/atlas/server/common/security/AtlasPamAuthenticationProvider.java
@@ -17,10 +17,10 @@
* under the License.
*/
-package org.apache.atlas.web.security;
+package org.apache.atlas.server.common.security;
import org.apache.atlas.ApplicationProperties;
-import org.apache.atlas.web.model.User;
+import org.apache.atlas.server.common.model.User;
import org.apache.commons.configuration.ConfigurationConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,11 +42,14 @@
import java.util.Map;
import java.util.Properties;
+import org.apache.atlas.server.common.security.AtlasAuthenticationException;
+import org.apache.atlas.server.common.security.UserAuthorityGranter;
+
@Component
public class AtlasPamAuthenticationProvider extends AtlasAbstractAuthenticationProvider {
private static final Logger LOG = LoggerFactory.getLogger(AtlasPamAuthenticationProvider.class);
- private static final String loginModuleName = "org.apache.atlas.web.security.PamLoginModule";
+ private static final String loginModuleName = "org.apache.atlas.server.common.security.PamLoginModule";
private static final AppConfigurationEntry.LoginModuleControlFlag controlFlag = AppConfigurationEntry.LoginModuleControlFlag.REQUIRED;
private final Map
+ * 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.atlas.server.common.service;
+
+/**
+ * ZooKeeper and HA connection parameters in a form shared code can use without importing
+ * webapp-specific or rest-notification-specific configuration classes.
+ */
+public class HighAvailabilityProperties {
+ private final String connectString;
+ private final String zkRoot;
+ private final int retriesSleepTimeMillis;
+ private final int numRetries;
+ private final int sessionTimeout;
+ private final String acl;
+ private final String auth;
+
+ public HighAvailabilityProperties(String connectString, String zkRoot, int retriesSleepTimeMillis, int numRetries,
+ int sessionTimeout, String acl, String auth) {
+ this.connectString = connectString;
+ this.zkRoot = zkRoot;
+ this.retriesSleepTimeMillis = retriesSleepTimeMillis;
+ this.numRetries = numRetries;
+ this.sessionTimeout = sessionTimeout;
+ this.acl = acl;
+ this.auth = auth;
+ }
+
+ public String getConnectString() {
+ return connectString;
+ }
+
+ public String getZkRoot() {
+ return zkRoot;
+ }
+
+ public int getRetriesSleepTimeMillis() {
+ return retriesSleepTimeMillis;
+ }
+
+ public int getNumRetries() {
+ return numRetries;
+ }
+
+ public int getSessionTimeout() {
+ return sessionTimeout;
+ }
+
+ public String getAcl() {
+ return acl;
+ }
+
+ public String getAuth() {
+ return auth;
+ }
+
+ public boolean hasAcl() {
+ return acl != null;
+ }
+
+ public boolean hasAuth() {
+ return auth != null;
+ }
+}
diff --git a/server-common/src/main/java/org/apache/atlas/server/common/service/HighAvailabilitySupport.java b/server-common/src/main/java/org/apache/atlas/server/common/service/HighAvailabilitySupport.java
new file mode 100644
index 0000000000..b371c2fa69
--- /dev/null
+++ b/server-common/src/main/java/org/apache/atlas/server/common/service/HighAvailabilitySupport.java
@@ -0,0 +1,88 @@
+/**
+ * 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.atlas.server.common.service;
+
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.ha.AtlasServerIdSelector;
+import org.apache.atlas.ha.HAConfiguration;
+import org.apache.commons.configuration.Configuration;
+
+/**
+ * Interface to abstract High Availability (HA) configuration retrieval.
+ * Enables shared services in {@code atlas-server-common} to operate without direct
+ * dependencies on application-specific configuration classes.
+ */
+public interface HighAvailabilitySupport {
+
+ /**
+ * Determines if HA mode is active based on the provided configuration.
+ */
+ boolean isHAEnabled(Configuration configuration);
+
+ /**
+ * Resolves the unique ID for the current server instance.
+ * @throws AtlasException if the server ID cannot be resolved.
+ */
+ String selectServerId(Configuration configuration) throws AtlasException;
+
+ /**
+ * Retrieves the network address bound to a specific server ID.
+ */
+ String getBoundAddressForId(Configuration configuration, String serverId);
+
+ /**
+ * Extracts ZooKeeper connection and properties required.
+ */
+ HighAvailabilityProperties getZookeeperProperties(Configuration configuration);
+
+ /**
+ * {@link HAConfiguration}-backed implementation for unit tests and call sites
+ * that need a default without Spring (same contract as the webapp
+ * {@code @Component} adapter).
+ */
+ final class AtlasConfigurationDefaults implements HighAvailabilitySupport {
+ @Override
+ public boolean isHAEnabled(Configuration configuration) {
+ return HAConfiguration.isHAEnabled(configuration);
+ }
+
+ @Override
+ public String selectServerId(Configuration configuration) throws AtlasException {
+ return AtlasServerIdSelector.selectServerId(configuration);
+ }
+
+ @Override
+ public String getBoundAddressForId(Configuration configuration, String serverId) {
+ return HAConfiguration.getBoundAddressForId(configuration, serverId);
+ }
+
+ @Override
+ public HighAvailabilityProperties getZookeeperProperties(Configuration configuration) {
+ HAConfiguration.ZookeeperProperties p = HAConfiguration.getZookeeperProperties(configuration);
+
+ return new HighAvailabilityProperties(
+ p.getConnectString(),
+ p.getZkRoot(),
+ p.getRetriesSleepTimeMillis(),
+ p.getNumRetries(),
+ p.getSessionTimeout(),
+ p.getAcl(),
+ p.getAuth());
+ }
+ }
+}
diff --git a/webapp/src/main/java/org/apache/atlas/web/service/SecureEmbeddedServer.java b/server-common/src/main/java/org/apache/atlas/server/common/service/SecureEmbeddedServer.java
old mode 100755
new mode 100644
similarity index 99%
rename from webapp/src/main/java/org/apache/atlas/web/service/SecureEmbeddedServer.java
rename to server-common/src/main/java/org/apache/atlas/server/common/service/SecureEmbeddedServer.java
index c898861d57..ac81bcf8ca
--- a/webapp/src/main/java/org/apache/atlas/web/service/SecureEmbeddedServer.java
+++ b/server-common/src/main/java/org/apache/atlas/server/common/service/SecureEmbeddedServer.java
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-package org.apache.atlas.web.service;
+package org.apache.atlas.server.common.service;
import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasConfiguration;
diff --git a/server-common/src/main/java/org/apache/atlas/server/common/service/ServiceMetricsHook.java b/server-common/src/main/java/org/apache/atlas/server/common/service/ServiceMetricsHook.java
new file mode 100644
index 0000000000..3a01a86221
--- /dev/null
+++ b/server-common/src/main/java/org/apache/atlas/server/common/service/ServiceMetricsHook.java
@@ -0,0 +1,30 @@
+/**
+ * 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.atlas.server.common.service;
+
+/**
+ * Reacts to server lifecycle events; WARs may register beans (e.g. delegating to {@code AtlasMetricsUtil}).
+ */
+public interface ServiceMetricsHook {
+
+ default void onServerStart() {
+ }
+
+ default void onServerActivation() {
+ }
+}
diff --git a/webapp/src/main/java/org/apache/atlas/web/service/ServiceState.java b/server-common/src/main/java/org/apache/atlas/server/common/service/ServiceState.java
similarity index 58%
rename from webapp/src/main/java/org/apache/atlas/web/service/ServiceState.java
rename to server-common/src/main/java/org/apache/atlas/server/common/service/ServiceState.java
index b2e7dd705a..0c7a0ec470 100644
--- a/webapp/src/main/java/org/apache/atlas/web/service/ServiceState.java
+++ b/server-common/src/main/java/org/apache/atlas/server/common/service/ServiceState.java
@@ -6,9 +6,9 @@
* 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
- *
+ *
+ * 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.
@@ -16,26 +16,18 @@
* limitations under the License.
*/
-package org.apache.atlas.web.service;
+package org.apache.atlas.server.common.service;
-import org.apache.atlas.ApplicationProperties;
-import org.apache.atlas.AtlasException;
-import org.apache.atlas.RequestContext;
-import org.apache.atlas.exception.AtlasBaseException;
-import org.apache.atlas.ha.HAConfiguration;
-import org.apache.atlas.model.audit.AtlasAuditEntry;
-import org.apache.atlas.repository.audit.AtlasAuditService;
+import org.apache.atlas.server.common.filters.spi.ServiceStateProvider;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
+import javax.inject.Inject;
import javax.inject.Singleton;
-import java.util.Date;
-
import static com.google.common.base.Preconditions.checkState;
import static org.apache.atlas.AtlasConstants.ATLAS_MIGRATION_MODE_FILENAME;
@@ -47,26 +39,29 @@
*/
@Singleton
@Component
-public class ServiceState {
+public class ServiceState implements ServiceStateProvider {
private static final Logger LOG = LoggerFactory.getLogger(ServiceState.class);
- @Autowired
- AtlasAuditService auditService;
-
- private final Configuration configuration;
+ public enum ServiceStateValue {
+ ACTIVE,
+ PASSIVE,
+ BECOMING_ACTIVE,
+ BECOMING_PASSIVE,
+ MIGRATING
+ }
+ private Configuration configuration;
private volatile ServiceStateValue state;
+ private final HighAvailabilitySupport haSupport;
- public ServiceState() throws AtlasException {
- this(ApplicationProperties.get());
- }
-
- public ServiceState(Configuration configuration) {
+ @Inject
+ public ServiceState(Configuration configuration, HighAvailabilitySupport haSupport) {
this.configuration = configuration;
+ this.haSupport = haSupport;
- state = !HAConfiguration.isHAEnabled(configuration) ? ServiceStateValue.ACTIVE : ServiceStateValue.PASSIVE;
+ state = !haSupport.isHAEnabled(configuration) ? ServiceStateValue.ACTIVE : ServiceStateValue.PASSIVE;
- if (!StringUtils.isEmpty(configuration.getString(ATLAS_MIGRATION_MODE_FILENAME, ""))) {
+ if(!StringUtils.isEmpty(configuration.getString(ATLAS_MIGRATION_MODE_FILENAME, ""))) {
state = ServiceStateValue.MIGRATING;
}
}
@@ -75,75 +70,57 @@ public ServiceStateValue getState() {
return state;
}
- private void setState(ServiceStateValue newState) {
- checkState(HAConfiguration.isHAEnabled(configuration), "Cannot change state as requested, as HA is not enabled for this instance.");
-
- state = newState;
-
- auditServerStatus();
- }
-
public void becomingActive() {
LOG.warn("Instance becoming active from {}", state);
-
setState(ServiceStateValue.BECOMING_ACTIVE);
}
public void setActive() {
LOG.warn("Instance is active from {}", state);
-
setState(ServiceStateValue.ACTIVE);
}
public void becomingPassive() {
LOG.warn("Instance becoming passive from {}", state);
-
setState(ServiceStateValue.BECOMING_PASSIVE);
}
public void setPassive() {
LOG.warn("Instance is passive from {}", state);
-
setState(ServiceStateValue.PASSIVE);
}
+ @Override
public boolean isInstanceInTransition() {
ServiceStateValue state = getState();
-
- return state == ServiceStateValue.BECOMING_ACTIVE || state == ServiceStateValue.BECOMING_PASSIVE;
+ return state == ServiceStateValue.BECOMING_ACTIVE
+ || state == ServiceStateValue.BECOMING_PASSIVE;
}
public void setMigration() {
LOG.warn("Instance in {}", state);
-
setState(ServiceStateValue.MIGRATING);
}
+ @Override
public boolean isInstanceInMigration() {
return getState() == ServiceStateValue.MIGRATING;
}
- private void auditServerStatus() {
- if (state == ServiceState.ServiceStateValue.ACTIVE) {
- Date date = new Date();
-
- try {
- auditService.add(AtlasAuditEntry.AuditOperation.SERVER_START, EmbeddedServer.SERVER_START_TIME, date, null, null, 0);
- auditService.add(AtlasAuditEntry.AuditOperation.SERVER_STATE_ACTIVE, date, date, null, null, 0);
- } catch (AtlasBaseException e) {
- LOG.error("Exception occurred during audit", e);
- } finally {
- // In HA environment, after the server related audits are added, the request created are now cleared.
- RequestContext.clear();
- }
- }
+ @Override
+ public boolean isActive() {
+ return getState() == ServiceStateValue.ACTIVE;
}
- public enum ServiceStateValue {
- ACTIVE,
- PASSIVE,
- BECOMING_ACTIVE,
- BECOMING_PASSIVE,
- MIGRATING
+ @Override
+ public String getStateName() {
+ return getState().toString();
+ }
+
+ private void setState(ServiceStateValue newState) {
+ checkState(haSupport.isHAEnabled(configuration),
+ "Cannot change state as requested, as HA is not enabled for this instance.");
+
+ state = newState;
}
}
diff --git a/webapp/src/main/java/org/apache/atlas/web/service/UserService.java b/server-common/src/main/java/org/apache/atlas/server/common/service/UserService.java
similarity index 83%
rename from webapp/src/main/java/org/apache/atlas/web/service/UserService.java
rename to server-common/src/main/java/org/apache/atlas/server/common/service/UserService.java
index e0ea2b2c02..ab1eb820b3 100644
--- a/webapp/src/main/java/org/apache/atlas/web/service/UserService.java
+++ b/server-common/src/main/java/org/apache/atlas/server/common/service/UserService.java
@@ -15,10 +15,10 @@
* limitations under the License.
*/
-package org.apache.atlas.web.service;
+package org.apache.atlas.server.common.service;
-import org.apache.atlas.web.dao.UserDao;
-import org.apache.atlas.web.model.User;
+import org.apache.atlas.server.common.dao.UserDao;
+import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@@ -35,7 +35,7 @@ public UserService(UserDao userDao) {
}
@Override
- public User loadUserByUsername(final String username) throws UsernameNotFoundException {
+ public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {
return userDao.loadUserByUsername(username);
}
}
diff --git a/webapp/src/main/java/org/apache/atlas/web/setup/KerberosAwareListener.java b/server-common/src/main/java/org/apache/atlas/server/common/setup/KerberosAwareListener.java
similarity index 91%
rename from webapp/src/main/java/org/apache/atlas/web/setup/KerberosAwareListener.java
rename to server-common/src/main/java/org/apache/atlas/server/common/setup/KerberosAwareListener.java
index 5fb9848855..c89a7803c5 100644
--- a/webapp/src/main/java/org/apache/atlas/web/setup/KerberosAwareListener.java
+++ b/server-common/src/main/java/org/apache/atlas/server/common/setup/KerberosAwareListener.java
@@ -15,9 +15,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.atlas.web.setup;
+package org.apache.atlas.server.common.setup;
-import org.apache.atlas.web.listeners.LoginProcessor;
+import org.apache.atlas.server.common.listeners.LoginProcessor;
import org.springframework.web.context.ContextLoaderListener;
import javax.servlet.ServletContextEvent;
diff --git a/webapp/src/main/java/org/apache/atlas/web/util/DateTimeHelper.java b/server-common/src/main/java/org/apache/atlas/server/common/util/DateTimeHelper.java
old mode 100755
new mode 100644
similarity index 64%
rename from webapp/src/main/java/org/apache/atlas/web/util/DateTimeHelper.java
rename to server-common/src/main/java/org/apache/atlas/server/common/util/DateTimeHelper.java
index dbdcd98e42..f2cfb8c184
--- a/webapp/src/main/java/org/apache/atlas/web/util/DateTimeHelper.java
+++ b/server-common/src/main/java/org/apache/atlas/server/common/util/DateTimeHelper.java
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-package org.apache.atlas.web.util;
+package org.apache.atlas.server.common.util;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
@@ -28,17 +28,20 @@
* Support function to parse and format date.
*/
public final class DateTimeHelper {
- public static final String ISO8601_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
- private static final String DATE_PATTERN = "(2\\d\\d\\d|19\\d\\d)-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])T" + "([0-1][0-9]|2[0-3]):([0-5][0-9])Z";
- private static final Pattern PATTERN = Pattern.compile(DATE_PATTERN);
- private static final ThreadLocal
+ * 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.atlas.web.ha; + +import org.apache.atlas.AtlasException; +import org.apache.atlas.ha.AtlasServerIdSelector; +import org.apache.atlas.ha.HAConfiguration; +import org.apache.atlas.server.common.service.HighAvailabilityProperties; +import org.apache.atlas.server.common.service.HighAvailabilitySupport; +import org.apache.commons.configuration.Configuration; +import org.springframework.stereotype.Component; + +/** + * Webapp implementation of {@link HighAvailabilitySupport} using {@link HAConfiguration}. + */ +@Component +public class WebappHighAvailabilitySupport implements HighAvailabilitySupport { + @Override + public boolean isHAEnabled(Configuration configuration) { + return HAConfiguration.isHAEnabled(configuration); + } + + @Override + public String selectServerId(Configuration configuration) throws AtlasException { + return AtlasServerIdSelector.selectServerId(configuration); + } + + @Override + public String getBoundAddressForId(Configuration configuration, String serverId) { + return HAConfiguration.getBoundAddressForId(configuration, serverId); + } + + @Override + public HighAvailabilityProperties getZookeeperProperties(Configuration configuration) { + HAConfiguration.ZookeeperProperties props = HAConfiguration.getZookeeperProperties(configuration); + + return new HighAvailabilityProperties( + props.getConnectString(), + props.getZkRoot(), + props.getRetriesSleepTimeMillis(), + props.getNumRetries(), + props.getSessionTimeout(), + props.getAcl(), + props.getAuth()); + } +} diff --git a/webapp/src/main/java/org/apache/atlas/web/metrics/WebappAdminAuditHook.java b/webapp/src/main/java/org/apache/atlas/web/metrics/WebappAdminAuditHook.java new file mode 100644 index 0000000000..2613430382 --- /dev/null +++ b/webapp/src/main/java/org/apache/atlas/web/metrics/WebappAdminAuditHook.java @@ -0,0 +1,112 @@ +/** + * 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.atlas.web.metrics; + +import org.apache.atlas.exception.AtlasBaseException; +import org.apache.atlas.model.audit.AtlasAuditEntry.AuditOperation; +import org.apache.atlas.repository.audit.AtlasAuditService; +import org.apache.atlas.server.common.service.EmbeddedServer; +import org.apache.atlas.server.common.service.ServiceMetricsHook; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.inject.Inject; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Date; + +/** + * Persists {@code SERVER_START} and {@code SERVER_STATE_ACTIVE} rows for Administration → Audits. + *
+ * Registered alongside {@link WebappServiceMetricsHook} as a {@link ServiceMetricsHook} so lifecycle + * matches {@link org.apache.atlas.server.common.service.ActiveInstanceElectorService}: non-HA invokes + * both hooks in sequence; HA emits {@code SERVER_START} at process init and {@code SERVER_STATE_ACTIVE} + * when this instance becomes leader. + *
+ * Uses the eight-argument {@link AtlasAuditService#add} overload so user and client id are explicit + * and do not rely on {@link org.apache.atlas.RequestContext} during bootstrap. + */ +@Component +public class WebappAdminAuditHook implements ServiceMetricsHook { + private static final Logger LOG = LoggerFactory.getLogger(WebappAdminAuditHook.class); + + private static final String ADMIN_AUDIT_USER = "atlas"; + + private final AtlasAuditService auditService; + + @Inject + public WebappAdminAuditHook(AtlasAuditService auditService) { + this.auditService = auditService; + } + + @Override + public void onServerStart() { + try { + Date endTime = new Date(); + auditService.add( + ADMIN_AUDIT_USER, + AuditOperation.SERVER_START, + clientIdForAudit(), + EmbeddedServer.SERVER_START_TIME, + endTime, + null, + null, + 0); + } catch (AtlasBaseException e) { + LOG.warn("Failed to write SERVER_START admin audit", e); + } + } + + @Override + public void onServerActivation() { + try { + Date now = new Date(); + auditService.add( + ADMIN_AUDIT_USER, + AuditOperation.SERVER_STATE_ACTIVE, + clientIdForAudit(), + now, + now, + null, + null, + 0); + } catch (AtlasBaseException e) { + LOG.warn("Failed to write SERVER_STATE_ACTIVE admin audit", e); + } + } + + /** + * Aligns with {@link AtlasAuditService#add} behavior when no HTTP client is present: host:address. + */ + private static String clientIdForAudit() { + try { + InetAddress local = InetAddress.getLocalHost(); + String hostName = StringUtils.defaultString(local.getHostName()); + String hostAddress = StringUtils.defaultString(local.getHostAddress()); + if (StringUtils.isNotEmpty(hostName) && StringUtils.isNotEmpty(hostAddress)) { + return hostName + ":" + hostAddress; + } + } catch (UnknownHostException e) { + LOG.debug("Could not resolve local host for audit client id", e); + } + return "unknown"; + } +} diff --git a/webapp/src/main/java/org/apache/atlas/web/metrics/WebappServiceMetricsHook.java b/webapp/src/main/java/org/apache/atlas/web/metrics/WebappServiceMetricsHook.java new file mode 100644 index 0000000000..c2a5e00340 --- /dev/null +++ b/webapp/src/main/java/org/apache/atlas/web/metrics/WebappServiceMetricsHook.java @@ -0,0 +1,47 @@ +/** + * 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.atlas.web.metrics; + +import org.apache.atlas.server.common.service.ServiceMetricsHook; +import org.apache.atlas.util.AtlasMetricsUtil; +import org.springframework.stereotype.Component; + +import javax.inject.Inject; + +/** + * Bridges {@link ServiceMetricsHook} to {@link AtlasMetricsUtil} in the main webapp. + */ +@Component +public class WebappServiceMetricsHook implements ServiceMetricsHook { + private final AtlasMetricsUtil metricsUtil; + + @Inject + public WebappServiceMetricsHook(AtlasMetricsUtil metricsUtil) { + this.metricsUtil = metricsUtil; + } + + @Override + public void onServerStart() { + metricsUtil.onServerStart(); + } + + @Override + public void onServerActivation() { + metricsUtil.onServerActivation(); + } +} diff --git a/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java b/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java index b092d48068..9df94d9688 100755 --- a/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java +++ b/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java @@ -67,6 +67,9 @@ import org.apache.atlas.repository.impexp.ZipSink; import org.apache.atlas.repository.patches.AtlasPatchManager; import org.apache.atlas.repository.store.graph.AtlasEntityStore; +import org.apache.atlas.server.common.filters.AtlasCSRFPreventionFilter; +import org.apache.atlas.server.common.service.ServiceState; +import org.apache.atlas.server.common.util.Servlets; import org.apache.atlas.services.MetricsService; import org.apache.atlas.services.PurgeService; import org.apache.atlas.tasks.TaskManagement; @@ -76,11 +79,8 @@ import org.apache.atlas.util.SearchTracker; import org.apache.atlas.utils.AtlasJson; import org.apache.atlas.utils.AtlasPerfTracer; -import org.apache.atlas.web.filters.AtlasCSRFPreventionFilter; import org.apache.atlas.web.model.DebugMetrics; import org.apache.atlas.web.service.AtlasDebugMetricsSink; -import org.apache.atlas.web.service.ServiceState; -import org.apache.atlas.web.util.Servlets; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; @@ -133,7 +133,7 @@ import java.util.stream.Collectors; import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT; -import static org.apache.atlas.web.filters.AtlasCSRFPreventionFilter.CSRF_TOKEN; +import static org.apache.atlas.server.common.filters.AtlasCSRFPreventionFilter.CSRF_TOKEN; /** * Jersey Resource for admin operations. diff --git a/webapp/src/main/java/org/apache/atlas/web/resources/DataSetLineageResource.java b/webapp/src/main/java/org/apache/atlas/web/resources/DataSetLineageResource.java index 0c14be1988..469c161a79 100644 --- a/webapp/src/main/java/org/apache/atlas/web/resources/DataSetLineageResource.java +++ b/webapp/src/main/java/org/apache/atlas/web/resources/DataSetLineageResource.java @@ -25,13 +25,13 @@ import org.apache.atlas.model.lineage.AtlasLineageInfo; import org.apache.atlas.model.lineage.AtlasLineageInfo.LineageDirection; import org.apache.atlas.repository.store.graph.AtlasEntityStore; +import org.apache.atlas.server.common.util.Servlets; import org.apache.atlas.type.AtlasEntityType; import org.apache.atlas.type.AtlasTypeRegistry; import org.apache.atlas.utils.AtlasPerfTracer; import org.apache.atlas.v1.model.lineage.DataSetLineageResponse; import org.apache.atlas.v1.model.lineage.SchemaResponse; import org.apache.atlas.web.util.LineageUtils; -import org.apache.atlas.web.util.Servlets; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java b/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java index 7d6e829a42..ccf66c5950 100755 --- a/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java +++ b/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java @@ -39,6 +39,7 @@ import org.apache.atlas.repository.store.graph.AtlasEntityStore; import org.apache.atlas.repository.store.graph.v2.AtlasEntityStream; import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2; +import org.apache.atlas.server.common.util.Servlets; import org.apache.atlas.type.AtlasEntityType; import org.apache.atlas.type.AtlasType; import org.apache.atlas.type.AtlasTypeRegistry; @@ -50,7 +51,6 @@ import org.apache.atlas.v1.model.instance.Referenceable; import org.apache.atlas.v1.model.instance.Struct; import org.apache.atlas.web.rest.EntityREST; -import org.apache.atlas.web.util.Servlets; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; diff --git a/webapp/src/main/java/org/apache/atlas/web/resources/LineageResource.java b/webapp/src/main/java/org/apache/atlas/web/resources/LineageResource.java index 61ceca3e52..6dca03e32d 100644 --- a/webapp/src/main/java/org/apache/atlas/web/resources/LineageResource.java +++ b/webapp/src/main/java/org/apache/atlas/web/resources/LineageResource.java @@ -22,12 +22,12 @@ import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.model.lineage.AtlasLineageInfo; import org.apache.atlas.model.lineage.AtlasLineageInfo.LineageDirection; +import org.apache.atlas.server.common.util.Servlets; import org.apache.atlas.type.AtlasTypeRegistry; import org.apache.atlas.utils.AtlasPerfTracer; import org.apache.atlas.v1.model.lineage.LineageResponse; import org.apache.atlas.v1.model.lineage.SchemaResponse; import org.apache.atlas.web.util.LineageUtils; -import org.apache.atlas.web.util.Servlets; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; diff --git a/webapp/src/main/java/org/apache/atlas/web/resources/MetadataDiscoveryResource.java b/webapp/src/main/java/org/apache/atlas/web/resources/MetadataDiscoveryResource.java index 280e13760e..da6fb90740 100755 --- a/webapp/src/main/java/org/apache/atlas/web/resources/MetadataDiscoveryResource.java +++ b/webapp/src/main/java/org/apache/atlas/web/resources/MetadataDiscoveryResource.java @@ -27,13 +27,13 @@ import org.apache.atlas.query.QueryParams; import org.apache.atlas.repository.converters.AtlasInstanceConverter; import org.apache.atlas.repository.store.graph.AtlasEntityStore; +import org.apache.atlas.server.common.util.Servlets; import org.apache.atlas.utils.AtlasJson; import org.apache.atlas.utils.AtlasPerfTracer; import org.apache.atlas.utils.ParamChecker; import org.apache.atlas.v1.model.discovery.DSLSearchResult; import org.apache.atlas.v1.model.discovery.FullTextSearchResult; import org.apache.atlas.v1.model.instance.Referenceable; -import org.apache.atlas.web.util.Servlets; import org.apache.commons.collections.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/webapp/src/main/java/org/apache/atlas/web/resources/TypesResource.java b/webapp/src/main/java/org/apache/atlas/web/resources/TypesResource.java index 8451997fc8..b05bd4dc08 100755 --- a/webapp/src/main/java/org/apache/atlas/web/resources/TypesResource.java +++ b/webapp/src/main/java/org/apache/atlas/web/resources/TypesResource.java @@ -24,13 +24,13 @@ import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.model.typedef.AtlasTypesDef; import org.apache.atlas.repository.converters.TypeConverterUtil; +import org.apache.atlas.server.common.util.Servlets; import org.apache.atlas.store.AtlasTypeDefStore; import org.apache.atlas.type.AtlasTypeRegistry; import org.apache.atlas.utils.AtlasJson; import org.apache.atlas.utils.AtlasPerfTracer; import org.apache.atlas.v1.model.typedef.TypesDef; import org.apache.atlas.web.rest.TypesREST; -import org.apache.atlas.web.util.Servlets; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java index 6f404a656f..1719653b77 100644 --- a/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java +++ b/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java @@ -38,12 +38,12 @@ import org.apache.atlas.model.profile.AtlasUserSavedSearch; import org.apache.atlas.repository.Constants; import org.apache.atlas.repository.store.graph.v2.tasks.searchdownload.SearchResultDownloadTask; +import org.apache.atlas.server.common.util.Servlets; import org.apache.atlas.type.AtlasEntityType; import org.apache.atlas.type.AtlasStructType; import org.apache.atlas.type.AtlasTypeRegistry; import org.apache.atlas.utils.AtlasJson; import org.apache.atlas.utils.AtlasPerfTracer; -import org.apache.atlas.web.util.Servlets; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.configuration.Configuration; import org.apache.commons.lang3.StringUtils; diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java index 07f142d82a..1f0e380cda 100644 --- a/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java +++ b/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java @@ -45,12 +45,12 @@ import org.apache.atlas.repository.store.graph.v2.AtlasEntityStream; import org.apache.atlas.repository.store.graph.v2.ClassificationAssociator; import org.apache.atlas.repository.store.graph.v2.EntityStream; +import org.apache.atlas.server.common.util.Servlets; import org.apache.atlas.type.AtlasClassificationType; import org.apache.atlas.type.AtlasEntityType; import org.apache.atlas.type.AtlasTypeRegistry; import org.apache.atlas.util.FileUtils; import org.apache.atlas.utils.AtlasPerfTracer; -import org.apache.atlas.web.util.Servlets; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/GlossaryREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/GlossaryREST.java index a9b7196674..e83a10d16f 100644 --- a/webapp/src/main/java/org/apache/atlas/web/rest/GlossaryREST.java +++ b/webapp/src/main/java/org/apache/atlas/web/rest/GlossaryREST.java @@ -32,8 +32,8 @@ import org.apache.atlas.model.glossary.relations.AtlasRelatedCategoryHeader; import org.apache.atlas.model.glossary.relations.AtlasRelatedTermHeader; import org.apache.atlas.model.instance.AtlasRelatedObjectId; +import org.apache.atlas.server.common.util.Servlets; import org.apache.atlas.utils.AtlasPerfTracer; -import org.apache.atlas.web.util.Servlets; import org.apache.commons.collections.MapUtils; import org.slf4j.Logger; import org.springframework.stereotype.Service; diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/IndexRecoveryREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/IndexRecoveryREST.java index 78ebd52c04..df379f8290 100644 --- a/webapp/src/main/java/org/apache/atlas/web/rest/IndexRecoveryREST.java +++ b/webapp/src/main/java/org/apache/atlas/web/rest/IndexRecoveryREST.java @@ -27,9 +27,9 @@ import org.apache.atlas.repository.graph.IndexRecoveryService; import org.apache.atlas.repository.graphdb.AtlasGraph; import org.apache.atlas.repository.graphdb.AtlasVertex; +import org.apache.atlas.server.common.util.DateTimeHelper; +import org.apache.atlas.server.common.util.Servlets; import org.apache.atlas.utils.AtlasPerfTracer; -import org.apache.atlas.web.util.DateTimeHelper; -import org.apache.atlas.web.util.Servlets; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.springframework.format.annotation.DateTimeFormat; diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/LineageREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/LineageREST.java index 54b6269985..ef3a94b46e 100644 --- a/webapp/src/main/java/org/apache/atlas/web/rest/LineageREST.java +++ b/webapp/src/main/java/org/apache/atlas/web/rest/LineageREST.java @@ -28,10 +28,10 @@ import org.apache.atlas.model.lineage.AtlasLineageInfo.LineageDirection; import org.apache.atlas.model.lineage.LineageOnDemandConstraints; import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2; +import org.apache.atlas.server.common.util.Servlets; import org.apache.atlas.type.AtlasEntityType; import org.apache.atlas.type.AtlasTypeRegistry; import org.apache.atlas.utils.AtlasPerfTracer; -import org.apache.atlas.web.util.Servlets; import org.apache.commons.collections.MapUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/NotificationREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/NotificationREST.java index d0c8a736fa..6c437ea98b 100644 --- a/webapp/src/main/java/org/apache/atlas/web/rest/NotificationREST.java +++ b/webapp/src/main/java/org/apache/atlas/web/rest/NotificationREST.java @@ -29,8 +29,8 @@ import org.apache.atlas.kafka.KafkaNotification; import org.apache.atlas.notification.NotificationException; import org.apache.atlas.notification.NotificationInterface; +import org.apache.atlas.server.common.util.Servlets; import org.apache.atlas.utils.AtlasJson; -import org.apache.atlas.web.util.Servlets; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/RelationshipREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/RelationshipREST.java index db64802d40..6f79c3442c 100644 --- a/webapp/src/main/java/org/apache/atlas/web/rest/RelationshipREST.java +++ b/webapp/src/main/java/org/apache/atlas/web/rest/RelationshipREST.java @@ -23,8 +23,8 @@ import org.apache.atlas.model.instance.AtlasRelationship; import org.apache.atlas.model.instance.AtlasRelationship.AtlasRelationshipWithExtInfo; import org.apache.atlas.repository.store.graph.AtlasRelationshipStore; +import org.apache.atlas.server.common.util.Servlets; import org.apache.atlas.utils.AtlasPerfTracer; -import org.apache.atlas.web.util.Servlets; import org.slf4j.Logger; import org.springframework.stereotype.Service; diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/TypesREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/TypesREST.java index e42b7627b1..d68bf1b7ac 100644 --- a/webapp/src/main/java/org/apache/atlas/web/rest/TypesREST.java +++ b/webapp/src/main/java/org/apache/atlas/web/rest/TypesREST.java @@ -30,10 +30,10 @@ import org.apache.atlas.model.typedef.AtlasTypeDefHeader; import org.apache.atlas.model.typedef.AtlasTypesDef; import org.apache.atlas.repository.util.FilterUtil; +import org.apache.atlas.server.common.util.Servlets; import org.apache.atlas.store.AtlasTypeDefStore; import org.apache.atlas.type.AtlasTypeUtil; import org.apache.atlas.utils.AtlasPerfTracer; -import org.apache.atlas.web.util.Servlets; import org.apache.http.annotation.Experimental; import org.slf4j.Logger; import org.springframework.stereotype.Service; diff --git a/webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationProvider.java b/webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationProvider.java index 3cff9fb8ee..c16efc6317 100644 --- a/webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationProvider.java +++ b/webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationProvider.java @@ -18,6 +18,12 @@ package org.apache.atlas.web.security; import org.apache.atlas.ApplicationProperties; +import org.apache.atlas.server.common.security.AtlasADAuthenticationProvider; +import org.apache.atlas.server.common.security.AtlasAbstractAuthenticationProvider; +import org.apache.atlas.server.common.security.AtlasAuthenticationException; +import org.apache.atlas.server.common.security.AtlasFileAuthenticationProvider; +import org.apache.atlas.server.common.security.AtlasLdapAuthenticationProvider; +import org.apache.atlas.server.common.security.AtlasPamAuthenticationProvider; import org.apache.commons.configuration.Configuration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/webapp/src/main/java/org/apache/atlas/web/security/AtlasKeycloakAuthenticationProvider.java b/webapp/src/main/java/org/apache/atlas/web/security/AtlasKeycloakAuthenticationProvider.java index 9839a21951..d639565e98 100644 --- a/webapp/src/main/java/org/apache/atlas/web/security/AtlasKeycloakAuthenticationProvider.java +++ b/webapp/src/main/java/org/apache/atlas/web/security/AtlasKeycloakAuthenticationProvider.java @@ -30,7 +30,7 @@ import java.util.Map; @Component -public class AtlasKeycloakAuthenticationProvider extends AtlasAbstractAuthenticationProvider { +public class AtlasKeycloakAuthenticationProvider extends org.apache.atlas.server.common.security.AtlasAbstractAuthenticationProvider { private final boolean groupsFromUGI; private final String groupsClaim; diff --git a/webapp/src/main/java/org/apache/atlas/web/security/AtlasSecurityConfig.java b/webapp/src/main/java/org/apache/atlas/web/security/AtlasSecurityConfig.java index 5058ebdf53..de7218b911 100644 --- a/webapp/src/main/java/org/apache/atlas/web/security/AtlasSecurityConfig.java +++ b/webapp/src/main/java/org/apache/atlas/web/security/AtlasSecurityConfig.java @@ -17,13 +17,15 @@ */ package org.apache.atlas.web.security; -import org.apache.atlas.web.filters.ActiveServerFilter; -import org.apache.atlas.web.filters.AtlasAuthenticationEntryPoint; -import org.apache.atlas.web.filters.AtlasAuthenticationFilter; -import org.apache.atlas.web.filters.AtlasCSRFPreventionFilter; -import org.apache.atlas.web.filters.AtlasDelegatingAuthenticationEntryPoint; -import org.apache.atlas.web.filters.AtlasKnoxSSOAuthenticationFilter; -import org.apache.atlas.web.filters.HeadersUtil; +import org.apache.atlas.server.common.filters.ActiveServerFilter; +import org.apache.atlas.server.common.filters.AtlasAuthenticationEntryPoint; +import org.apache.atlas.server.common.filters.AtlasAuthenticationFilter; +import org.apache.atlas.server.common.filters.AtlasCSRFPreventionFilter; +import org.apache.atlas.server.common.filters.AtlasDelegatingAuthenticationEntryPoint; +import org.apache.atlas.server.common.filters.AtlasKnoxSSOAuthenticationFilter; +import org.apache.atlas.server.common.filters.HeadersUtil; +import org.apache.atlas.server.common.security.AtlasAuthenticationFailureHandler; +import org.apache.atlas.server.common.security.AtlasAuthenticationSuccessHandler; import org.apache.atlas.web.filters.StaleTransactionCleanupFilter; import org.apache.commons.configuration.Configuration; import org.apache.commons.lang3.StringUtils; @@ -80,7 +82,7 @@ import java.util.Map; import static org.apache.atlas.AtlasConstants.ATLAS_MIGRATION_MODE_FILENAME; -import static org.apache.atlas.web.filters.HeadersUtil.SERVER_KEY; +import static org.apache.atlas.server.common.filters.HeadersUtil.SERVER_KEY; @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) diff --git a/webapp/src/main/java/org/apache/atlas/web/security/AtlasSecurityFilterBeansConfig.java b/webapp/src/main/java/org/apache/atlas/web/security/AtlasSecurityFilterBeansConfig.java new file mode 100644 index 0000000000..5bdb667864 --- /dev/null +++ b/webapp/src/main/java/org/apache/atlas/web/security/AtlasSecurityFilterBeansConfig.java @@ -0,0 +1,71 @@ +/** + * 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.atlas.web.security;
+
+import org.apache.atlas.server.common.filters.ActiveServerFilter;
+import org.apache.atlas.server.common.filters.AtlasAuthenticationFilter;
+import org.apache.atlas.server.common.filters.AtlasCSRFPreventionFilter;
+import org.apache.atlas.server.common.filters.AtlasKnoxSSOAuthenticationFilter;
+import org.apache.atlas.server.common.filters.spi.ActiveInstanceStateProvider;
+import org.apache.atlas.server.common.filters.spi.AtlasAuthenticationProviderBridge;
+import org.apache.atlas.server.common.filters.spi.ServiceStateProvider;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AtlasSecurityFilterBeansConfig {
+ @Bean
+ public AtlasAuthenticationProviderBridge atlasAuthenticationProviderBridge(AtlasAuthenticationProvider authenticationProvider) {
+ return new AtlasAuthenticationProviderBridge() {
+ @Override
+ public java.util.List
+ * 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.atlas.web.security;
+
+import org.apache.atlas.server.common.filters.spi.ActiveInstanceStateProvider;
+import org.apache.atlas.server.common.filters.spi.ServiceStateProvider;
+import org.apache.atlas.server.common.service.ActiveInstanceState;
+import org.apache.atlas.server.common.service.ServiceState;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AtlasSecurityStateProviderConfig {
+ @Bean
+ public ActiveInstanceStateProvider activeInstanceStateProvider(ActiveInstanceState activeInstanceState) {
+ return activeInstanceState::getActiveServerAddress;
+ }
+
+ @Bean
+ public ServiceStateProvider serviceStateProvider(ServiceState serviceState) {
+ return new ServiceStateProvider() {
+ @Override
+ public boolean isActive() {
+ return serviceState.getState() == ServiceState.ServiceStateValue.ACTIVE;
+ }
+
+ @Override
+ public boolean isInstanceInTransition() {
+ return serviceState.isInstanceInTransition();
+ }
+
+ @Override
+ public boolean isInstanceInMigration() {
+ return serviceState.isInstanceInMigration();
+ }
+
+ @Override
+ public String getStateName() {
+ return serviceState.getState().toString();
+ }
+ };
+ }
+}
diff --git a/webapp/src/main/java/org/apache/atlas/web/servlets/AtlasHttpServlet.java b/webapp/src/main/java/org/apache/atlas/web/servlets/AtlasHttpServlet.java
index 04566a378c..988831eadb 100644
--- a/webapp/src/main/java/org/apache/atlas/web/servlets/AtlasHttpServlet.java
+++ b/webapp/src/main/java/org/apache/atlas/web/servlets/AtlasHttpServlet.java
@@ -17,8 +17,8 @@
*/
package org.apache.atlas.web.servlets;
-import org.apache.atlas.web.filters.AtlasResponseRequestWrapper;
-import org.apache.atlas.web.filters.HeadersUtil;
+import org.apache.atlas.server.common.filters.AtlasResponseRequestWrapper;
+import org.apache.atlas.server.common.filters.HeadersUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/webapp/src/main/java/org/apache/atlas/web/setup/SetupSteps.java b/webapp/src/main/java/org/apache/atlas/web/setup/SetupSteps.java
index b7f5ec4a39..b789160428 100644
--- a/webapp/src/main/java/org/apache/atlas/web/setup/SetupSteps.java
+++ b/webapp/src/main/java/org/apache/atlas/web/setup/SetupSteps.java
@@ -24,10 +24,10 @@
import org.apache.atlas.AtlasException;
import org.apache.atlas.ha.AtlasServerIdSelector;
import org.apache.atlas.ha.HAConfiguration;
+import org.apache.atlas.server.common.service.AtlasZookeeperSecurityProperties;
+import org.apache.atlas.server.common.service.CuratorFactory;
import org.apache.atlas.setup.SetupException;
import org.apache.atlas.setup.SetupStep;
-import org.apache.atlas.web.service.AtlasZookeeperSecurityProperties;
-import org.apache.atlas.web.service.CuratorFactory;
import org.apache.commons.configuration.Configuration;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
diff --git a/webapp/src/main/java/org/apache/atlas/web/util/AtlasJsonProvider.java b/webapp/src/main/java/org/apache/atlas/web/util/AtlasJsonProvider.java
index e675a36457..a34c405e95 100644
--- a/webapp/src/main/java/org/apache/atlas/web/util/AtlasJsonProvider.java
+++ b/webapp/src/main/java/org/apache/atlas/web/util/AtlasJsonProvider.java
@@ -23,6 +23,7 @@
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
+import org.apache.atlas.server.common.util.Servlets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
diff --git a/webapp/src/main/resources/spring-security.xml b/webapp/src/main/resources/spring-security.xml
index 3020690dca..a507b14b4a 100644
--- a/webapp/src/main/resources/spring-security.xml
+++ b/webapp/src/main/resources/spring-security.xml
@@ -54,23 +54,23 @@
+ * 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.atlas.web.metrics;
+
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.audit.AtlasAuditEntry.AuditOperation;
+import org.apache.atlas.repository.audit.AtlasAuditService;
+import org.apache.atlas.server.common.service.EmbeddedServer;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.Date;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+public class WebappAdminAuditHookTest {
+ private static final String ATLAS_USER = "atlas";
+
+ @Mock
+ private AtlasAuditService auditService;
+
+ private WebappAdminAuditHook hook;
+
+ @BeforeMethod
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ hook = new WebappAdminAuditHook(auditService);
+ }
+
+ @Test
+ public void testOnServerStartInvokesAuditWithServerStartOperation() throws AtlasBaseException {
+ hook.onServerStart();
+
+ verify(auditService, times(1)).add(
+ eq(ATLAS_USER),
+ eq(AuditOperation.SERVER_START),
+ anyString(),
+ eq(EmbeddedServer.SERVER_START_TIME),
+ any(Date.class),
+ isNull(),
+ isNull(),
+ eq(0L));
+ }
+
+ @Test
+ public void testOnServerActivationInvokesAuditWithServerStateActiveOperation() throws AtlasBaseException {
+ hook.onServerActivation();
+
+ ArgumentCaptor
+ * Profile-gated so classpath scanning for embedded-server / full webapp tests does not import
+ * {@code test-spring-security.xml} alongside {@link AtlasSecurityConfig} (that overlap creates a
+ * circular dependency between the Knox SSO filter and {@code atlasAuthenticationProviderBridge}).
+ */
+@Configuration
+@Profile("testSpringSecurityBridge")
+@ImportResource("classpath:test-spring-security.xml")
+public class TestSpringSecurityBridgeConfig {
+ @Bean
+ public AtlasAuthenticationProviderBridge atlasAuthenticationProviderBridge(AtlasAuthenticationProvider authenticationProvider) {
+ return new AtlasAuthenticationProviderBridge() {
+ @Override
+ public List