YARN-5294. Pass remote ip address down to YarnAuthorizationProvider. (Jian He via wangda)
This commit is contained in:
parent
d792a90206
commit
04f6ebb66a
|
@ -18,8 +18,12 @@
|
|||
|
||||
package org.apache.hadoop.yarn.security;
|
||||
|
||||
import org.apache.hadoop.classification.InterfaceAudience.Public;
|
||||
import org.apache.hadoop.classification.InterfaceStability.Unstable;
|
||||
import org.apache.hadoop.security.UserGroupInformation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This request object contains all the context information to determine whether
|
||||
* a user has permission to access the target entity.
|
||||
|
@ -30,7 +34,14 @@ import org.apache.hadoop.security.UserGroupInformation;
|
|||
* if no app is associated.
|
||||
* appName : the associated app name for current access. This could be null if
|
||||
* no app is associated.
|
||||
* remoteAddress : The caller's remote ip address.
|
||||
* forwardedAddresses : In case this is an http request, this contains the
|
||||
* originating IP address of a client connecting to a web
|
||||
* server through an HTTP proxy or load balancer. This
|
||||
* parameter is null, if it's a RPC request.
|
||||
*/
|
||||
@Public
|
||||
@Unstable
|
||||
public class AccessRequest {
|
||||
|
||||
private PrivilegedEntity entity;
|
||||
|
@ -38,14 +49,19 @@ public class AccessRequest {
|
|||
private AccessType accessType;
|
||||
private String appId;
|
||||
private String appName;
|
||||
private String remoteAddress;
|
||||
private List<String> forwardedAddresses;
|
||||
|
||||
public AccessRequest(PrivilegedEntity entity, UserGroupInformation user,
|
||||
AccessType accessType, String appId, String appName) {
|
||||
AccessType accessType, String appId, String appName, String remoteAddress,
|
||||
List<String> forwardedAddresses) {
|
||||
this.entity = entity;
|
||||
this.user = user;
|
||||
this.accessType = accessType;
|
||||
this.appId = appId;
|
||||
this.appName = appName;
|
||||
this.remoteAddress = remoteAddress;
|
||||
this.forwardedAddresses = forwardedAddresses;
|
||||
}
|
||||
|
||||
public UserGroupInformation getUser() {
|
||||
|
@ -67,4 +83,13 @@ public class AccessRequest {
|
|||
public PrivilegedEntity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
public List<String> getForwardedAddresses() {
|
||||
return forwardedAddresses;
|
||||
}
|
||||
|
||||
public String getRemoteAddress() {
|
||||
return remoteAddress;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -307,7 +307,8 @@ public class ClientRMService extends AbstractService implements
|
|||
return applicationsACLsManager
|
||||
.checkAccess(callerUGI, operationPerformed, owner,
|
||||
application.getApplicationId()) || queueACLsManager
|
||||
.checkAccess(callerUGI, QueueACL.ADMINISTER_QUEUE, application);
|
||||
.checkAccess(callerUGI, QueueACL.ADMINISTER_QUEUE, application,
|
||||
Server.getRemoteAddress(), null);
|
||||
}
|
||||
|
||||
ApplicationId getNewApplicationId() {
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.io.DataInputByteBuffer;
|
||||
import org.apache.hadoop.ipc.Server;
|
||||
import org.apache.hadoop.security.AccessControlException;
|
||||
import org.apache.hadoop.security.Credentials;
|
||||
import org.apache.hadoop.security.UserGroupInformation;
|
||||
|
@ -370,11 +371,13 @@ public class RMAppManager implements EventHandler<RMAppManagerEvent>,
|
|||
&& !authorizer.checkPermission(
|
||||
new AccessRequest(csqueue.getPrivilegedEntity(), userUgi,
|
||||
SchedulerUtils.toAccessType(QueueACL.SUBMIT_APPLICATIONS),
|
||||
applicationId.toString(), appName))
|
||||
applicationId.toString(), appName, Server.getRemoteAddress(),
|
||||
null))
|
||||
&& !authorizer.checkPermission(
|
||||
new AccessRequest(csqueue.getPrivilegedEntity(), userUgi,
|
||||
SchedulerUtils.toAccessType(QueueACL.ADMINISTER_QUEUE),
|
||||
applicationId.toString(), appName))) {
|
||||
applicationId.toString(), appName, Server.getRemoteAddress(),
|
||||
null))) {
|
||||
throw new AccessControlException(
|
||||
"User " + user + " does not have permission to submit "
|
||||
+ applicationId + " to queue " + submissionContext.getQueue());
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.apache.commons.lang.StringUtils;
|
|||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.hadoop.classification.InterfaceAudience.Private;
|
||||
import org.apache.hadoop.ipc.Server;
|
||||
import org.apache.hadoop.security.UserGroupInformation;
|
||||
import org.apache.hadoop.security.authorize.AccessControlList;
|
||||
import org.apache.hadoop.yarn.api.records.Priority;
|
||||
|
@ -199,7 +200,7 @@ public abstract class AbstractCSQueue implements CSQueue {
|
|||
public boolean hasAccess(QueueACL acl, UserGroupInformation user) {
|
||||
return authorizer.checkPermission(
|
||||
new AccessRequest(queueEntity, user, SchedulerUtils.toAccessType(acl),
|
||||
null, null));
|
||||
null, null, Server.getRemoteAddress(), null));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package org.apache.hadoop.yarn.server.resourcemanager.security;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
|
@ -26,15 +27,14 @@ import org.apache.hadoop.yarn.api.records.QueueACL;
|
|||
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
||||
import org.apache.hadoop.yarn.security.AccessRequest;
|
||||
import org.apache.hadoop.yarn.security.YarnAuthorizationProvider;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.ResourceTrackerService;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerUtils;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CSQueue;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class QueueACLsManager {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(QueueACLsManager.class);
|
||||
|
@ -56,7 +56,7 @@ public class QueueACLsManager {
|
|||
}
|
||||
|
||||
public boolean checkAccess(UserGroupInformation callerUGI, QueueACL acl,
|
||||
RMApp app) {
|
||||
RMApp app, String remoteAddress, List<String> forwardedAddresses) {
|
||||
if (!isACLsEnable) {
|
||||
return true;
|
||||
}
|
||||
|
@ -71,11 +71,11 @@ public class QueueACLsManager {
|
|||
.getApplicationId());
|
||||
return true;
|
||||
}
|
||||
|
||||
return authorizer.checkPermission(
|
||||
new AccessRequest(queue.getPrivilegedEntity(), callerUGI,
|
||||
SchedulerUtils.toAccessType(acl),
|
||||
app.getApplicationId().toString(), app.getName()));
|
||||
app.getApplicationId().toString(), app.getName(),
|
||||
remoteAddress, forwardedAddresses));
|
||||
} else {
|
||||
return scheduler.checkAccess(callerUGI, acl, app.getQueue());
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.security.AccessControlException;
|
|||
import java.security.Principal;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
|
@ -228,12 +229,18 @@ public class RMWebServices extends WebServices {
|
|||
protected Boolean hasAccess(RMApp app, HttpServletRequest hsr) {
|
||||
// Check for the authorization.
|
||||
UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true);
|
||||
List<String> forwardedAddresses = null;
|
||||
String forwardedFor = hsr.getHeader("X-Forwarded-For");
|
||||
if (forwardedFor != null) {
|
||||
forwardedAddresses = Arrays.asList(forwardedFor.split(","));
|
||||
}
|
||||
if (callerUGI != null
|
||||
&& !(this.rm.getApplicationACLsManager().checkAccess(callerUGI,
|
||||
ApplicationAccessType.VIEW_APP, app.getUser(),
|
||||
app.getApplicationId()) ||
|
||||
this.rm.getQueueACLsManager().checkAccess(callerUGI,
|
||||
QueueACL.ADMINISTER_QUEUE, app))) {
|
||||
QueueACL.ADMINISTER_QUEUE, app, hsr.getRemoteAddr(),
|
||||
forwardedAddresses))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -112,7 +112,8 @@ public class TestApplicationACLs {
|
|||
Configuration conf) {
|
||||
QueueACLsManager mockQueueACLsManager = mock(QueueACLsManager.class);
|
||||
when(mockQueueACLsManager.checkAccess(any(UserGroupInformation.class),
|
||||
any(QueueACL.class), any(RMApp.class))).thenAnswer(new Answer() {
|
||||
any(QueueACL.class), any(RMApp.class), any(String.class),
|
||||
any())).thenAnswer(new Answer() {
|
||||
public Object answer(InvocationOnMock invocation) {
|
||||
return isQueueUser;
|
||||
}
|
||||
|
|
|
@ -474,7 +474,8 @@ public class TestClientRMService {
|
|||
QueueACLsManager mockQueueACLsManager = mock(QueueACLsManager.class);
|
||||
when(
|
||||
mockQueueACLsManager.checkAccess(any(UserGroupInformation.class),
|
||||
any(QueueACL.class), any(RMApp.class))).thenReturn(true);
|
||||
any(QueueACL.class), any(RMApp.class), any(String.class),
|
||||
any())).thenReturn(true);
|
||||
return new ClientRMService(rmContext, yarnScheduler, appManager,
|
||||
mockAclsManager, mockQueueACLsManager, null);
|
||||
}
|
||||
|
@ -575,7 +576,9 @@ public class TestClientRMService {
|
|||
ApplicationACLsManager mockAclsManager = mock(ApplicationACLsManager.class);
|
||||
QueueACLsManager mockQueueACLsManager = mock(QueueACLsManager.class);
|
||||
when(mockQueueACLsManager.checkAccess(any(UserGroupInformation.class),
|
||||
any(QueueACL.class), any(RMApp.class))).thenReturn(true);
|
||||
any(QueueACL.class), any(RMApp.class), any(String.class),
|
||||
any()))
|
||||
.thenReturn(true);
|
||||
when(mockAclsManager.checkAccess(any(UserGroupInformation.class),
|
||||
any(ApplicationAccessType.class), anyString(),
|
||||
any(ApplicationId.class))).thenReturn(true);
|
||||
|
@ -601,7 +604,9 @@ public class TestClientRMService {
|
|||
QueueACLsManager mockQueueACLsManager1 =
|
||||
mock(QueueACLsManager.class);
|
||||
when(mockQueueACLsManager1.checkAccess(any(UserGroupInformation.class),
|
||||
any(QueueACL.class), any(RMApp.class))).thenReturn(false);
|
||||
any(QueueACL.class), any(RMApp.class), any(String.class),
|
||||
any()))
|
||||
.thenReturn(false);
|
||||
when(mockAclsManager1.checkAccess(any(UserGroupInformation.class),
|
||||
any(ApplicationAccessType.class), anyString(),
|
||||
any(ApplicationId.class))).thenReturn(false);
|
||||
|
@ -640,7 +645,9 @@ public class TestClientRMService {
|
|||
|
||||
QueueACLsManager mockQueueACLsManager = mock(QueueACLsManager.class);
|
||||
when(mockQueueACLsManager.checkAccess(any(UserGroupInformation.class),
|
||||
any(QueueACL.class), any(RMApp.class))).thenReturn(true);
|
||||
any(QueueACL.class), any(RMApp.class), any(String.class),
|
||||
any()))
|
||||
.thenReturn(true);
|
||||
ClientRMService rmService =
|
||||
new ClientRMService(rmContext, yarnScheduler, appManager,
|
||||
mockAclsManager, mockQueueACLsManager, null);
|
||||
|
@ -728,7 +735,9 @@ public class TestClientRMService {
|
|||
ApplicationACLsManager mockAclsManager = mock(ApplicationACLsManager.class);
|
||||
QueueACLsManager mockQueueACLsManager = mock(QueueACLsManager.class);
|
||||
when(mockQueueACLsManager.checkAccess(any(UserGroupInformation.class),
|
||||
any(QueueACL.class), any(RMApp.class))).thenReturn(true);
|
||||
any(QueueACL.class), any(RMApp.class), any(String.class),
|
||||
any()))
|
||||
.thenReturn(true);
|
||||
ClientRMService rmService =
|
||||
new ClientRMService(rmContext, yarnScheduler, appManager,
|
||||
mockAclsManager, mockQueueACLsManager, null);
|
||||
|
|
Loading…
Reference in New Issue