Skip to content

Commit

Permalink
AMBARI-25171. Backport Knox Trusted Proxy changes into 2.7.4 (amagyar) (
Browse files Browse the repository at this point in the history
  • Loading branch information
zeroflag committed Mar 12, 2019
1 parent e89e204 commit 1529ef2
Show file tree
Hide file tree
Showing 112 changed files with 3,174 additions and 586 deletions.
Expand Up @@ -903,20 +903,22 @@ private void addRequestToAuditlogCache(Request request) {
RequestDetails requestDetails = new RequestDetails();
requestDetails.setNumberOfTasks(numberOfTasks);
requestDetails.setUserName(AuthorizationHelper.getAuthenticatedName());
requestDetails.setProxyUserName(AuthorizationHelper.getProxyUserName());
auditlogRequestCache.put(request.getRequestId(), requestDetails);
}
}

/**
* AuditLog operation status change
*
* @param requestId
*/
private void auditLog(HostRoleCommandEntity commandEntity, Long requestId) {
if(!auditLogger.isEnabled()) {
if (!auditLogger.isEnabled()) {
return;
}

if(requestId != null) {
if (requestId != null) {
HostRoleStatus lastTaskStatus = updateAuditlogCache(commandEntity, requestId);

// details must not be null
Expand All @@ -928,12 +930,13 @@ private void auditLog(HostRoleCommandEntity commandEntity, Long requestId) {
RequestEntity request = requestDAO.findByPK(requestId);
String context = request != null ? request.getRequestContext() : null;
AuditEvent auditEvent = OperationStatusAuditEvent.builder()
.withRequestId(String.valueOf(requestId))
.withStatus(String.valueOf(calculatedStatus))
.withRequestContext(context)
.withUserName(details.getUserName())
.withTimestamp(System.currentTimeMillis())
.build();
.withRequestId(String.valueOf(requestId))
.withStatus(String.valueOf(calculatedStatus))
.withRequestContext(context)
.withUserName(details.getUserName())
.withProxyUserName(details.getProxyUserName())
.withTimestamp(System.currentTimeMillis())
.build();
auditLogger.log(auditEvent);

details.setLastStatus(calculatedStatus);
Expand Down Expand Up @@ -978,6 +981,7 @@ private void logTask(HostRoleCommandEntity commandEntity, Long requestId, HostRo
.withTaskId(String.valueOf(commandEntity.getTaskId()))
.withHostName(commandEntity.getHostName())
.withUserName(details.getUserName())
.withProxyUserName(details.getProxyUserName())
.withOperation(commandEntity.getRoleCommand() + " " + commandEntity.getRole())
.withDetails(commandEntity.getCommandDetail())
.withStatus(commandEntity.getStatus().toString())
Expand Down Expand Up @@ -1014,6 +1018,11 @@ private static class RequestDetails {
*/
Map<Component, HostRoleStatus> tasks = new HashMap<>();

/**
* Name of the proxy user if proxied
*/
private String proxyUserName;

public HostRoleStatus getLastStatus() {
return lastStatus;
}
Expand Down Expand Up @@ -1050,6 +1059,14 @@ public Collection<HostRoleStatus> getTaskStatuses() {
return getTasks().values();
}

public String getProxyUserName() {
return proxyUserName;
}

public void setProxyUserName(String proxyUserName) {
this.proxyUserName = proxyUserName;
}

/**
* This nested class is the key for the {@link RequestDetails#tasks} map
*/
Expand Down
Expand Up @@ -75,7 +75,7 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques

if ((code == HttpServletResponse.SC_FORBIDDEN) || (code == HttpServletResponse.SC_UNAUTHORIZED)) {
//if SSO is configured we should provide info about it in case of access error
JwtAuthenticationProperties jwtProperties = jwtAuthenticationPropertiesProvider.getProperties();
JwtAuthenticationProperties jwtProperties = jwtAuthenticationPropertiesProvider.get();
if ((jwtProperties != null) && jwtProperties.isEnabledForAmbari()) {
String providerUrl = jwtProperties.getAuthenticationProviderUrl();
String originalUrl = jwtProperties.getOriginalUrlQueryParam();
Expand Down
Expand Up @@ -53,6 +53,7 @@ public class QueryLexer {
public static final String QUERY_FROM = "from";
public static final String QUERY_MINIMAL = "minimal_response";
public static final String QUERY_SORT = "sortBy";
public static final String QUERY_DOAS = "doAs";

/**
* All valid deliminators.
Expand Down Expand Up @@ -216,6 +217,7 @@ private Pattern generatePattern() {
SET_IGNORE.add(QUERY_FROM);
SET_IGNORE.add(QUERY_MINIMAL);
SET_IGNORE.add(QUERY_SORT);
SET_IGNORE.add(QUERY_DOAS);
SET_IGNORE.add("_");
}

Expand Down
Expand Up @@ -65,6 +65,7 @@ private void auditLog(HttpServletRequest servletRequest) {
.withTimestamp(System.currentTimeMillis())
.withRemoteIp(RequestUtils.getRemoteAddress(servletRequest))
.withUserName(AuthorizationHelper.getAuthenticatedName())
.withProxyUserName(AuthorizationHelper.getProxyUserName())
.build();
auditLogger.log(logoutEvent);
}
Expand Down
Expand Up @@ -19,6 +19,7 @@
package org.apache.ambari.server.audit.event;

import org.apache.ambari.server.security.authorization.AuthorizationHelper;
import org.apache.commons.lang.StringUtils;

/**
* Base class for audit events which are result of user actions. It appends
Expand All @@ -35,6 +36,11 @@ public static abstract class AbstractUserAuditEventBuilder<T extends AbstractUse
*/
private String userName = AuthorizationHelper.getAuthenticatedName();

/**
* Name of the proxy user if proxied
*/
private String proxyUserName = AuthorizationHelper.getProxyUserName();

/**
* Ip of the user who started the operation. Note: remote ip might not be the original ip (proxies, routers can modify it)
*/
Expand All @@ -58,6 +64,12 @@ protected void buildAuditMessage(StringBuilder builder) {
.append("), RemoteIp(")
.append(this.remoteIp)
.append(")");
if (StringUtils.isNotEmpty(this.proxyUserName)){
builder
.append(", ProxyUser(")
.append(this.proxyUserName)
.append(")");
}
}

/**
Expand All @@ -72,6 +84,18 @@ public TBuilder withUserName(String userName) {
return self();
}

/**
* Sets the proxy user name.
*
* @param proxyUserName
* @return the builder
*/
public TBuilder withProxyUserName(String proxyUserName) {
this.proxyUserName = proxyUserName;

return self();
}

/**
* Sets the remote ip where the user action originated from.
*
Expand Down
Expand Up @@ -25,9 +25,9 @@
* Audit event for tracking operations
*/
@Immutable
public class OperationStatusAuditEvent extends AbstractAuditEvent {
public class OperationStatusAuditEvent extends AbstractUserAuditEvent {

public static class OperationStatusAuditEventBuilder extends AbstractAuditEventBuilder<OperationStatusAuditEvent, OperationStatusAuditEventBuilder> {
public static class OperationStatusAuditEventBuilder extends AbstractUserAuditEventBuilder<OperationStatusAuditEvent, OperationStatusAuditEventBuilder> {

/**
* Request identifier
Expand All @@ -44,11 +44,6 @@ public static class OperationStatusAuditEventBuilder extends AbstractAuditEventB
*/
private String operation;

/**
* Name of the logged in user who sent the request
*/
private String userName;

private OperationStatusAuditEventBuilder() {
super(OperationStatusAuditEventBuilder.class);
}
Expand All @@ -65,10 +60,9 @@ protected OperationStatusAuditEvent newAuditEvent() {
*/
@Override
protected void buildAuditMessage(StringBuilder builder) {
super.buildAuditMessage(builder);
builder
.append("User(")
.append(this.userName)
.append("), Operation(")
.append(", Operation(")
.append(this.operation)
.append("), Status(")
.append(this.status)
Expand All @@ -92,11 +86,6 @@ public OperationStatusAuditEventBuilder withRequestContext(String operation) {
this.operation = operation;
return this;
}

public OperationStatusAuditEventBuilder withUserName(String userName) {
this.userName = userName;
return this;
}
}

private OperationStatusAuditEvent() {
Expand Down
Expand Up @@ -25,9 +25,9 @@
* Audit event for tracking task status
*/
@Immutable
public class TaskStatusAuditEvent extends AbstractAuditEvent {
public class TaskStatusAuditEvent extends AbstractUserAuditEvent {

public static class TaskStatusAuditEventBuilder extends AbstractAuditEventBuilder<TaskStatusAuditEvent, TaskStatusAuditEventBuilder> {
public static class TaskStatusAuditEventBuilder extends AbstractUserAuditEventBuilder<TaskStatusAuditEvent, TaskStatusAuditEventBuilder> {

/**
* Request identifier
Expand Down Expand Up @@ -59,11 +59,6 @@ public static class TaskStatusAuditEventBuilder extends AbstractAuditEventBuilde
*/
private String details;

/**
* User name
*/
private String userName;

private TaskStatusAuditEventBuilder() {
super(TaskStatusAuditEventBuilder.class);
}
Expand All @@ -80,10 +75,9 @@ protected TaskStatusAuditEvent newAuditEvent() {
*/
@Override
protected void buildAuditMessage(StringBuilder builder) {
super.buildAuditMessage(builder);
builder
.append("User(")
.append(this.userName)
.append("), Operation(")
.append(", Operation(")
.append(this.operation);

if (details != null) {
Expand Down Expand Up @@ -132,10 +126,6 @@ public TaskStatusAuditEventBuilder withDetails(String details) {
this.details = details;
return this;
}
public TaskStatusAuditEventBuilder withUserName(String userName) {
this.userName = userName;
return this;
}
}

private TaskStatusAuditEvent() {
Expand Down
@@ -0,0 +1,68 @@
/*
* 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.ambari.server.configuration;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* AmbariServerConfiguration is an abstract class to be extended by Ambari server configuration classes
* that encapsulate difference configuration categories such as 'ldap-configuration' and 'sso-configuration'.
*
* @see AmbariServerConfigurationCategory
* @see AmbariServerConfigurationKey
*/
public abstract class AmbariServerConfiguration {

private static final Logger LOGGER = LoggerFactory.getLogger(AmbariServerConfiguration.class);

/**
* Gets the configuration value for given {@link AmbariServerConfigurationKey}.
* <p>
* If no value is found in the supplied configuration map, the default value will be returned.
*
* @param ambariServerConfigurationKey the {@link AmbariServerConfigurationKey} for which to retrieve a value
* @param configurationMap a map of configuration property names to values
* @return the requested configuration value
*/
protected String getValue(AmbariServerConfigurationKey ambariServerConfigurationKey, Map<String, String> configurationMap) {
return getValue(ambariServerConfigurationKey.key(), configurationMap, ambariServerConfigurationKey.getDefaultValue());
}

/**
* Gets the configuration value for given {@link AmbariServerConfigurationKey}.
* <p>
* If no value is found in the supplied configuration map, the default value will be returned.
*
* @param propertyName the property name for which to retrieve a value
* @param configurationMap a map of configuration property names to values
* @param defaultValue the default value to use in the event the propery was not set in the configuration map
* @return the requested configuration value
*/
protected String getValue(String propertyName, Map<String, String> configurationMap, String defaultValue) {
if ((configurationMap != null) && configurationMap.containsKey(propertyName)) {
return configurationMap.get(propertyName);
} else {
LOGGER.debug("Ambari server configuration property [{}] hasn't been set; using default value", propertyName);
return defaultValue;
}
}

}
Expand Up @@ -19,15 +19,19 @@
package org.apache.ambari.server.configuration;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* AmbariServerConfigurationCategory is an enumeration of the different Ambari server specific
* configuration categories.
*/
public enum AmbariServerConfigurationCategory {
LDAP_CONFIGURATION("ldap-configuration"),
SSO_CONFIGURATION("sso-configuration");
SSO_CONFIGURATION("sso-configuration"),
TPROXY_CONFIGURATION("tproxy-configuration");

private static final Logger LOG = LoggerFactory.getLogger(AmbariServerConfigurationCategory.class);
private final String categoryName;

AmbariServerConfigurationCategory(String categoryName) {
Expand All @@ -54,7 +58,8 @@ public static AmbariServerConfigurationCategory translate(String categoryName) {
}
}

throw new IllegalArgumentException(String.format("Invalid Ambari server configuration category name: %s", categoryName));
LOG.warn("Invalid Ambari server configuration category: {}", categoryName);
return null;
}

/**
Expand Down

0 comments on commit 1529ef2

Please sign in to comment.