This is an automated email from the ASF dual-hosted git repository.
avijayan pushed a commit to branch HDDS-4944
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/HDDS-4944 by this push:
new e5fb5b0 HDDS-5476. [Multi-Tenant] Support Ozone s3 authentication
with arbitrary accessId that is not same as the kerberos ID (#2635)
e5fb5b0 is described below
commit e5fb5b02eb528d8cc9a6724cdad76e5271aaee1a
Author: avijayanhwx <[email protected]>
AuthorDate: Wed Sep 22 13:58:43 2021 -0700
HDDS-5476. [Multi-Tenant] Support Ozone s3 authentication with arbitrary
accessId that is not same as the kerberos ID (#2635)
---
.../ozone/security/OzoneTokenIdentifier.java | 37 +++++++++++++++++++---
.../hadoop/ozone/om/OMMultiTenantManager.java | 6 ++++
.../hadoop/ozone/om/OMMultiTenantManagerImpl.java | 24 ++++++++++++++
.../org/apache/hadoop/ozone/om/OzoneManager.java | 1 +
.../OzoneDelegationTokenSecretManager.java | 18 ++++++++++-
.../ozone/security/TestOzoneTokenIdentifier.java | 18 +++++++++++
6 files changed, 99 insertions(+), 5 deletions(-)
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/OzoneTokenIdentifier.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/OzoneTokenIdentifier.java
index 01fcaf8..a62dd15 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/OzoneTokenIdentifier.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/OzoneTokenIdentifier.java
@@ -23,6 +23,7 @@ import java.io.DataOutput;
import java.io.IOException;
import java.time.Instant;
import java.util.Arrays;
+import java.util.function.UnaryOperator;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.hadoop.hdds.annotation.InterfaceAudience;
@@ -33,7 +34,10 @@ import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableUtils;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMTokenProto;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMTokenProto.Type;
+import org.apache.hadoop.security.UserGroupInformation;
import
org.apache.hadoop.security.token.delegation.AbstractDelegationTokenIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import static
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMTokenProto.Type.S3AUTHINFO;
@@ -46,6 +50,9 @@ import static
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.
public class OzoneTokenIdentifier extends
AbstractDelegationTokenIdentifier {
+ private static final Logger LOG =
+ LoggerFactory.getLogger(OzoneTokenIdentifier.class);
+
public static final Text KIND_NAME = new Text("OzoneToken");
private String omCertSerialId;
private Type tokenType;
@@ -54,6 +61,10 @@ public class OzoneTokenIdentifier extends
private String strToSign;
private String omServiceId;
+ // Function to convert an arbitrary accessId to the kerberos user that owns
+ // the accessId.
+ private UnaryOperator<String> getUserForAccessId;
+
/**
* Create an empty delegation token identifier.
*/
@@ -107,10 +118,24 @@ public class OzoneTokenIdentifier extends
return buf.getData();
}
- /** Instead of relying on proto deserialization, this
- * provides explicit deserialization for OzoneTokenIdentifier.
- * @return byte[]
- */
+ @Override
+ public UserGroupInformation getUser() {
+ if (getUserForAccessId != null && tokenType.equals(S3AUTHINFO)) {
+ // Should have been passed as accessId
+ String tokenUser = getOwner().toString();
+ String actualUserName = getUserForAccessId.apply(tokenUser);
+ if (actualUserName != null) {
+ LOG.debug("S3 Token user for {} : {}", tokenUser, actualUserName);
+ return UserGroupInformation.createRemoteUser(actualUserName);
+ }
+ }
+ return super.getUser();
+ }
+
+ /** Instead of relying on proto deserialization, this
+ * provides explicit deserialization for OzoneTokenIdentifier.
+ * @return byte[]
+ */
public OzoneTokenIdentifier fromUniqueSerializedKey(byte[] rawData)
throws IOException {
DataInputBuffer in = new DataInputBuffer();
@@ -368,6 +393,10 @@ public class OzoneTokenIdentifier extends
this.strToSign = strToSign;
}
+ public void setGetUserForAccessId(UnaryOperator<String> func) {
+ this.getUserForAccessId = func;
+ }
+
@Override
public String toString() {
StringBuilder buffer = new StringBuilder();
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManager.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManager.java
index d9eacdf..ccae7f9 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManager.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManager.java
@@ -129,6 +129,12 @@ public interface OMMultiTenantManager {
*/
void destroyUser(String tenantName, String userName);
+
+ /**
+ * Given an accessId, return kerberos user name for the tenant user.
+ */
+ String getUserNameGivenAccessId(String accessId);
+
/**
* Given a user, return their S3-Secret Key.
* @param user
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManagerImpl.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManagerImpl.java
index a9e0962..8237214 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManagerImpl.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManagerImpl.java
@@ -42,6 +42,7 @@ import java.util.stream.Collectors;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.ozone.om.helpers.OmDBAccessIdInfo;
import org.apache.hadoop.ozone.om.multitenant.AccessPolicy;
import org.apache.hadoop.ozone.om.multitenant.AccountNameSpace;
import org.apache.hadoop.ozone.om.multitenant.BucketNameSpace;
@@ -59,6 +60,8 @@ import org.apache.http.auth.BasicUserPrincipal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
+
/**
* Implements OMMultiTenantManager.
*/
@@ -369,6 +372,27 @@ public class OMMultiTenantManagerImpl implements
OMMultiTenantManager {
}
@Override
+ public String getUserNameGivenAccessId(String accessId) {
+ Preconditions.checkNotNull(accessId);
+ try {
+ controlPathLock.readLock().lock();
+ OmDBAccessIdInfo omDBAccessIdInfo =
+ omMetadataManager.getTenantAccessIdTable().get(accessId);
+ if (omDBAccessIdInfo != null) {
+ String userName = omDBAccessIdInfo.getKerberosPrincipal();
+ LOG.debug("Username for accessId {} = {}", accessId, userName);
+ return userName;
+ }
+ } catch (IOException ioEx) {
+ LOG.error("Unexpected error while obtaining DB Access Info for {}",
+ accessId, ioEx);
+ } finally {
+ controlPathLock.readLock().unlock();
+ }
+ return null;
+ }
+
+ @Override
public String getUserSecret(OzoneMultiTenantPrincipal user)
throws IOException {
return "";
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
index af85efb..bf4e3ee 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
@@ -802,6 +802,7 @@ public final class OzoneManager extends
ServiceRuntimeInfoImpl
.setS3SecretManager(s3SecretManager)
.setCertificateClient(certClient)
.setOmServiceId(omNodeDetails.getServiceId())
+ .setOMMultiTenantManager(multiTenantManagr)
.build();
}
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/security/OzoneDelegationTokenSecretManager.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/security/OzoneDelegationTokenSecretManager.java
index 5d34f6a..a433e10 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/security/OzoneDelegationTokenSecretManager.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/security/OzoneDelegationTokenSecretManager.java
@@ -36,6 +36,7 @@ import
org.apache.hadoop.hdds.security.x509.certificate.client.CertificateClient
import org.apache.hadoop.hdds.security.x509.exceptions.CertificateException;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.ozone.om.OMConfigKeys;
+import org.apache.hadoop.ozone.om.OMMultiTenantManager;
import org.apache.hadoop.ozone.om.S3SecretManager;
import org.apache.hadoop.ozone.om.S3SecretManagerImpl;
import org.apache.hadoop.ozone.om.exceptions.OMException;
@@ -71,6 +72,7 @@ public class OzoneDelegationTokenSecretManager
private final long tokenRemoverScanInterval;
private String omCertificateSerialId;
private String omServiceId;
+ private OMMultiTenantManager multiTenantManager;
/**
* If the delegation token update thread holds this lock, it will not get
@@ -97,6 +99,7 @@ public class OzoneDelegationTokenSecretManager
isRatisEnabled = b.ozoneConf.getBoolean(
OMConfigKeys.OZONE_OM_RATIS_ENABLE_KEY,
OMConfigKeys.OZONE_OM_RATIS_ENABLE_DEFAULT);
+ this.multiTenantManager = b.omMultiTenantManager;
loadTokenSecretState(store.loadState());
}
@@ -111,6 +114,7 @@ public class OzoneDelegationTokenSecretManager
private long tokenRemoverScanInterval;
private Text service;
private S3SecretManager s3SecretManager;
+ private OMMultiTenantManager omMultiTenantManager;
private CertificateClient certClient;
private String omServiceId;
@@ -157,11 +161,23 @@ public class OzoneDelegationTokenSecretManager
this.omServiceId = serviceId;
return this;
}
+
+ public Builder setOMMultiTenantManager(OMMultiTenantManager
+ multiTenantManager) {
+ this.omMultiTenantManager = multiTenantManager;
+ return this;
+ }
+
}
@Override
public OzoneTokenIdentifier createIdentifier() {
- return OzoneTokenIdentifier.newInstance();
+ OzoneTokenIdentifier tokenId = OzoneTokenIdentifier.newInstance();
+ if (multiTenantManager != null) {
+ tokenId.setGetUserForAccessId(
+ multiTenantManager::getUserNameGivenAccessId);
+ }
+ return tokenId;
}
/**
diff --git
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestOzoneTokenIdentifier.java
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestOzoneTokenIdentifier.java
index 48ed205..2ac8d4c 100644
---
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestOzoneTokenIdentifier.java
+++
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestOzoneTokenIdentifier.java
@@ -17,6 +17,8 @@
*/
package org.apache.hadoop.ozone.security;
+import static
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMTokenProto.Type.S3AUTHINFO;
+
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
@@ -346,4 +348,20 @@ public class TestOzoneTokenIdentifier {
Assert.assertEquals("Deserialize Serialized Token should equal.",
idWrite, idRead);
}
+
+ @Test
+ public void testGetUserFromAccessIdInToken() {
+ OzoneTokenIdentifier id = getIdentifierInst();
+ Assert.assertEquals("User1", id.getUser().getUserName());
+
+ id.setTokenType(S3AUTHINFO);
+ Assert.assertEquals("User1", id.getUser().getUserName());
+
+ id.setGetUserForAccessId(s -> "modified-" + s);
+ Assert.assertEquals("modified-User1", id.getUser().getUserName());
+
+ id.setGetUserForAccessId(s -> null);
+ Assert.assertEquals("User1", id.getUser().getUserName());
+
+ }
}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]