This is an automated email from the ASF dual-hosted git repository. kbhatt pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/atlas.git
commit ec3c6dba44edc353adddb4f2d30decff2446e401 Author: chaitalicod <[email protected]> AuthorDate: Tue Feb 25 12:32:12 2020 +0530 ATLAS-3631: Make Server name header configurable and Basic auth improvement. Signed-off-by: kevalbhatt <[email protected]> --- .../java/org/apache/atlas/AtlasConfiguration.java | 5 +- .../AtlasDelegatingAuthenticationEntryPoint.java | 62 ++++++++++++++++++++++ .../org/apache/atlas/web/filters/HeadersUtil.java | 13 +++-- .../atlas/web/security/AtlasSecurityConfig.java | 10 ++-- 4 files changed, 80 insertions(+), 10 deletions(-) diff --git a/intg/src/main/java/org/apache/atlas/AtlasConfiguration.java b/intg/src/main/java/org/apache/atlas/AtlasConfiguration.java index 1a0d0cc..c5bf50d 100644 --- a/intg/src/main/java/org/apache/atlas/AtlasConfiguration.java +++ b/intg/src/main/java/org/apache/atlas/AtlasConfiguration.java @@ -64,7 +64,10 @@ public enum AtlasConfiguration { CUSTOM_ATTRIBUTE_VALUE_MAX_LENGTH("atlas.custom.attribute.value.max.length", 500), LABEL_MAX_LENGTH("atlas.entity.label.max.length", 50), IMPORT_TEMP_DIRECTORY("atlas.import.temp.directory", ""), - LINEAGE_USING_GREMLIN("atlas.lineage.query.use.gremlin", false); + MIGRATION_IMPORT_START_POSITION("atlas.migration.import.start.position", 0), + LINEAGE_USING_GREMLIN("atlas.lineage.query.use.gremlin", false), + + HTTP_HEADER_SERVER_VALUE("atlas.http.header.server.value","Apache Atlas"); private static final Configuration APPLICATION_PROPERTIES; diff --git a/webapp/src/main/java/org/apache/atlas/web/filters/AtlasDelegatingAuthenticationEntryPoint.java b/webapp/src/main/java/org/apache/atlas/web/filters/AtlasDelegatingAuthenticationEntryPoint.java new file mode 100644 index 0000000..c629a7e --- /dev/null +++ b/webapp/src/main/java/org/apache/atlas/web/filters/AtlasDelegatingAuthenticationEntryPoint.java @@ -0,0 +1,62 @@ +/* + * 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.filters; + +import java.io.IOException; +import java.util.LinkedHashMap; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.util.matcher.RequestMatcher; +import org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint; + +public class AtlasDelegatingAuthenticationEntryPoint extends DelegatingAuthenticationEntryPoint { + + public static final String SESSION_TIMEOUT = "Session Timeout"; + private static final Logger LOG = LoggerFactory.getLogger(AtlasDelegatingAuthenticationEntryPoint.class); + + public AtlasDelegatingAuthenticationEntryPoint(LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPoints) { + super(entryPoints); + if (LOG.isDebugEnabled()) { + LOG.info("AtlasDelegatingAuthenticationEntryPoint-AjaxAwareAuthenticationEntryPoint(): constructor"); + } + } + + public void commence(HttpServletRequest request, HttpServletResponse response, + AuthenticationException authException) throws IOException { + + String ajaxRequestHeader = request.getHeader(HeadersUtil.X_REQUESTED_WITH_KEY); + response.setHeader(HeadersUtil.X_FRAME_OPTIONS_KEY, HeadersUtil.X_FRAME_OPTIONS_VAL); + + if (ajaxRequestHeader != null + && HeadersUtil.X_REQUESTED_WITH_VALUE.equalsIgnoreCase(ajaxRequestHeader)) { + if (LOG.isDebugEnabled()) { + LOG.debug("commence() AJAX request. Authentication required. Returning " + + HttpServletResponse.SC_UNAUTHORIZED + ". URL=" + request.getRequestURI()); + } + response.sendError(HeadersUtil.SC_AUTHENTICATION_TIMEOUT, SESSION_TIMEOUT); + } else { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, + authException.getMessage()); + } + } +} diff --git a/webapp/src/main/java/org/apache/atlas/web/filters/HeadersUtil.java b/webapp/src/main/java/org/apache/atlas/web/filters/HeadersUtil.java index acae4f5..1f8845d 100644 --- a/webapp/src/main/java/org/apache/atlas/web/filters/HeadersUtil.java +++ b/webapp/src/main/java/org/apache/atlas/web/filters/HeadersUtil.java @@ -17,13 +17,13 @@ */ package org.apache.atlas.web.filters; +import org.apache.atlas.AtlasConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map; - @Component public class HeadersUtil { @@ -31,20 +31,23 @@ public class HeadersUtil { public static final Map<String, String> headerMap = new HashMap<>(); - public static final String X_FRAME_OPTIONS_KEY = "X-Frame-Options"; public static final String X_CONTENT_TYPE_OPTIONS_KEY = "X-Content-Type-Options"; public static final String X_XSS_PROTECTION_KEY = "X-XSS-Protection"; public static final String STRICT_TRANSPORT_SEC_KEY = "Strict-Transport-Security"; public static final String CONTENT_SEC_POLICY_KEY = "Content-Security-Policy"; - public static final String SERVER_KEY = "Server"; public static final String X_FRAME_OPTIONS_VAL = "DENY"; public static final String X_CONTENT_TYPE_OPTIONS_VAL = "nosniff"; public static final String X_XSS_PROTECTION_VAL = "1; mode=block"; public static final String STRICT_TRANSPORT_SEC_VAL = "max-age=31536000; includeSubDomains"; public static final String CONTENT_SEC_POLICY_VAL = "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: data:; connect-src 'self'; img-src 'self' blob: data:; style-src 'self' 'unsafe-inline';font-src 'self' data:"; - public static final String SERVER_VAL = "Apache Atlas"; + public static final String SERVER_KEY = "Server"; + public static final String USER_AGENT_KEY = "User-Agent"; + public static final String USER_AGENT_VALUE = "Mozilla"; + public static final String X_REQUESTED_WITH_KEY = "X-REQUESTED-WITH"; + public static final String X_REQUESTED_WITH_VALUE = "XMLHttpRequest"; + public static final int SC_AUTHENTICATION_TIMEOUT = 419; HeadersUtil() { headerMap.put(X_FRAME_OPTIONS_KEY, X_FRAME_OPTIONS_VAL); @@ -52,7 +55,7 @@ public class HeadersUtil { headerMap.put(X_XSS_PROTECTION_KEY, X_XSS_PROTECTION_VAL); headerMap.put(STRICT_TRANSPORT_SEC_KEY, STRICT_TRANSPORT_SEC_VAL); headerMap.put(CONTENT_SEC_POLICY_KEY, CONTENT_SEC_POLICY_VAL); - headerMap.put(SERVER_KEY, SERVER_VAL); + headerMap.put(SERVER_KEY, AtlasConfiguration.HTTP_HEADER_SERVER_VALUE.getString()); } public static void setHeaderMapAttributes(AtlasResponseRequestWrapper responseWrapper, String headerKey) { 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 498c0aa..e74a9e9 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 @@ -74,6 +74,7 @@ import java.util.List; import java.util.Map; import static org.apache.atlas.AtlasConstants.ATLAS_MIGRATION_MODE_FILENAME; +import static org.apache.atlas.web.filters.HeadersUtil.SERVER_KEY; @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) @@ -137,8 +138,9 @@ public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter { keycloakAuthenticationEntryPoint.setLoginUri("/login.jsp"); authenticationEntryPoint = keycloakAuthenticationEntryPoint; } else { - BasicAuthenticationEntryPoint basicAuthenticationEntryPoint = new BasicAuthenticationEntryPoint(); - basicAuthenticationEntryPoint.setRealmName("atlas.com"); + LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPointMap = new LinkedHashMap<>(); + entryPointMap.put(new RequestHeaderRequestMatcher(HeadersUtil.USER_AGENT_KEY, HeadersUtil.USER_AGENT_VALUE), atlasAuthenticationEntryPoint); + AtlasDelegatingAuthenticationEntryPoint basicAuthenticationEntryPoint = new AtlasDelegatingAuthenticationEntryPoint(entryPointMap); authenticationEntryPoint = basicAuthenticationEntryPoint; } return authenticationEntryPoint; @@ -146,7 +148,7 @@ public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter { public DelegatingAuthenticationEntryPoint getDelegatingAuthenticationEntryPoint() throws Exception { LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPointMap = new LinkedHashMap<>(); - entryPointMap.put(new RequestHeaderRequestMatcher("User-Agent", "Mozilla"), atlasAuthenticationEntryPoint); + entryPointMap.put(new RequestHeaderRequestMatcher(HeadersUtil.USER_AGENT_KEY, HeadersUtil.USER_AGENT_VALUE), atlasAuthenticationEntryPoint); DelegatingAuthenticationEntryPoint entryPoint = new DelegatingAuthenticationEntryPoint(entryPointMap); entryPoint.setDefaultEntryPoint(getAuthenticationEntryPoint()); return entryPoint; @@ -187,7 +189,7 @@ public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter { .and() .headers() .addHeaderWriter(new StaticHeadersWriter(HeadersUtil.CONTENT_SEC_POLICY_KEY, HeadersUtil.headerMap.get(HeadersUtil.CONTENT_SEC_POLICY_KEY))) - .addHeaderWriter(new StaticHeadersWriter(HeadersUtil.SERVER_KEY, HeadersUtil.headerMap.get(HeadersUtil.SERVER_KEY))) + .addHeaderWriter(new StaticHeadersWriter(SERVER_KEY, HeadersUtil.headerMap.get(SERVER_KEY))) .and() .servletApi() .and()
