diff --git a/pom.xml b/pom.xml index 70ab604..8f2b681 100644 --- a/pom.xml +++ b/pom.xml @@ -37,6 +37,7 @@ 2.17 2.24.1 + 1.19.2 3.3.2 3.12.1 diff --git a/src/main/java/tech/stackable/hadoop/StackableGroupMapper.java b/src/main/java/tech/stackable/hadoop/StackableGroupMapper.java index b1ee34a..f4bb2f4 100644 --- a/src/main/java/tech/stackable/hadoop/StackableGroupMapper.java +++ b/src/main/java/tech/stackable/hadoop/StackableGroupMapper.java @@ -4,29 +4,23 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Objects; - -import com.fasterxml.jackson.databind.type.TypeFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.security.GroupMappingServiceProvider; +import org.apache.hadoop.security.UserGroupInformation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class StackableGroupMapper implements GroupMappingServiceProvider { - private static final Logger LOG = LoggerFactory.getLogger(StackableGroupMapper.class); - public static final String OPA_MAPPING_URL_PROP = "hadoop.security.group.mapping.opa.policy.url"; - // response base field: see https://www.openpolicyagent.org/docs/latest/rest-api/#response-message - private static final String OPA_RESULT_FIELD = "result"; - + private static final Logger LOG = LoggerFactory.getLogger(StackableGroupMapper.class); private final HttpClient httpClient = HttpClient.newHttpClient(); private final ObjectMapper json; private URI opaUri; @@ -59,21 +53,36 @@ public StackableGroupMapper() { .setSerializationInclusion(JsonInclude.Include.NON_NULL); } - private static class OpaQueryResult { - public List result; - } - /** - * Returns list of groups for a user. + * Returns list of groups for a user. Internally Hadoop will pass the short name to this function, + * but this prevents us from effectively separating users with the same names but with different + * kerberos principals. For this reason the user name is extracted from the UserGroupInformation + * instead (giving us the full name), defaulting to the original name if this is not possible. * - * @param user get groups for this user + * @param user get groups from the associated user group information for this user * @return list of groups for a given user */ @Override public List getGroups(String user) { LOG.info("Calling StackableGroupMapper.getGroups for user \"{}\"", user); - OpaGroupsQuery query = new OpaGroupsQuery(new OpaGroupsQuery.OpaGroupsQueryInput(user)); + String workingUser = user; + try { + UserGroupInformation currentUser = UserGroupInformation.getCurrentUser(); + LOG.debug( + "Current user [{}] with user-name [{}] and short-name [{}]", + currentUser, + currentUser.getUserName(), + currentUser.getShortUserName()); + workingUser = currentUser.getUserName(); + } catch (IOException e) { + LOG.warn( + "Unable to extract name from UserGroupInformation, defaulting to \"{}\": {}", + user, + e.getMessage()); + } + + OpaGroupsQuery query = new OpaGroupsQuery(new OpaGroupsQuery.OpaGroupsQueryInput(workingUser)); String body; try { @@ -115,7 +124,7 @@ public List getGroups(String user) { } List groups = result.result; - LOG.debug("Groups for \"{}\": {}", user, groups); + LOG.debug("Groups for \"{}\": {}", workingUser, groups); return groups; } @@ -139,4 +148,8 @@ public void cacheGroupsAdd(List groups) { "ignoring cacheGroupsAdd for groups [{}]: caching should be provided by the policy provider", groups); } + + private static class OpaQueryResult { + public List result; + } }