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 c0b1ddbd1dd9..54eb7b940598 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 @@ -21,6 +21,7 @@ import java.io.DataInputStream; import java.io.DataOutput; import java.io.IOException; +import java.time.Instant; import java.util.Arrays; import org.apache.commons.lang3.builder.EqualsBuilder; @@ -374,8 +375,8 @@ public String toString() { .append(" owner=").append(getOwner()) .append(", renewer=").append(getRenewer()) .append(", realUser=").append(getRealUser()) - .append(", issueDate=").append(getIssueDate()) - .append(", maxDate=").append(getMaxDate()) + .append(", issueDate=").append(Instant.ofEpochMilli(getIssueDate())) + .append(", maxDate=").append(Instant.ofEpochMilli(getMaxDate())) .append(", sequenceNumber=").append(getSequenceNumber()) .append(", masterKeyId=").append(getMasterKeyId()) .append(", strToSign=").append(getStrToSign()) diff --git a/hadoop-ozone/dist/src/main/smoketest/security/ozone-secure-token.robot b/hadoop-ozone/dist/src/main/smoketest/security/ozone-secure-token.robot index 5823143638ba..a84d2efbcabe 100644 --- a/hadoop-ozone/dist/src/main/smoketest/security/ozone-secure-token.robot +++ b/hadoop-ozone/dist/src/main/smoketest/security/ozone-secure-token.robot @@ -22,9 +22,17 @@ Resource ../commonlib.robot Test Timeout 5 minutes *** Keywords *** -Get Token in Secure Cluster - Execute ozone sh token get > /tmp/token.txt - File Should Not Be Empty /tmp/token.txt +Get and use Token in Secure Cluster + Execute ozone sh token get -t /tmp/ozone.token + File Should Not Be Empty /tmp/ozone.token + Execute kdestroy + Set Environment Variable HADOOP_TOKEN_FILE_LOCATION /tmp/ozone.token + ${output} = Execute ozone sh volume list / + Should not contain ${output} Client cannot authenticate + Remove Environment Variable HADOOP_TOKEN_FILE_LOCATION + ${output} = Execute and Ignore Error ozone sh volume list / + Should contain ${output} Client cannot authenticate + Run Keyword Kinit test user testuser testuser.keytab Get Token in Unsecure Cluster ${output} = Execute ozone sh token get @@ -59,7 +67,7 @@ Cancel Token in Unsecure Cluster Should Contain ${output} only when security is enabled Token Test in Secure Cluster - Get Token in Secure Cluster + Get and use Token in Secure Cluster Print Valid Token File Renew Token in Secure Cluster Cancel Token in Secure Cluster diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/token/GetTokenHandler.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/token/GetTokenHandler.java index 5bf8ccb83eb0..d159d2233f95 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/token/GetTokenHandler.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/token/GetTokenHandler.java @@ -46,6 +46,9 @@ public class GetTokenHandler extends Handler { @CommandLine.Mixin private RenewerOption renewer; + @CommandLine.Mixin + private TokenOption tokenFile; + @Override protected OzoneAddress getAddress() throws OzoneClientException { return new OzoneAddress(uri); @@ -66,7 +69,10 @@ protected void execute(OzoneClient client, OzoneAddress address) err().println("Error: Get delegation token operation failed. " + "Check OzoneManager logs for more details."); } else { - printObjectAsJson(token.encodeToUrlString()); + out().println("Successfully get token for service " + + token.getService()); + out().println(token.toString()); + tokenFile.persistToken(token); } } } diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/token/PrintTokenHandler.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/token/PrintTokenHandler.java index 632a9d277487..ab02b76ad56a 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/token/PrintTokenHandler.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/token/PrintTokenHandler.java @@ -18,7 +18,6 @@ package org.apache.hadoop.ozone.shell.token; -import org.apache.hadoop.hdds.server.JsonUtils; import org.apache.hadoop.ozone.security.OzoneTokenIdentifier; import org.apache.hadoop.security.token.Token; @@ -42,7 +41,7 @@ public class PrintTokenHandler implements Callable { public Void call() throws Exception { if (tokenFile.exists()) { Token token = tokenFile.decode(); - System.out.print(JsonUtils.toJsonStringWithDefaultPrettyPrinter(token)); + System.out.println(token.toString()); } return null; } diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/token/RenewTokenHandler.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/token/RenewTokenHandler.java index 6b5e7a1e5129..581093050ae0 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/token/RenewTokenHandler.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/token/RenewTokenHandler.java @@ -24,6 +24,7 @@ import picocli.CommandLine.Command; import java.io.IOException; +import java.time.Instant; /** * Executes renewDelegationToken api. @@ -36,6 +37,7 @@ public class RenewTokenHandler extends TokenHandler { protected void execute(OzoneClient client, OzoneAddress address) throws IOException, OzoneClientException { long expiryTime = client.getObjectStore().renewDelegationToken(getToken()); - out().printf("Token renewed successfully, expiry time: %s.%n", expiryTime); + out().printf("Token renewed successfully, expiry time: %s.%n", + Instant.ofEpochMilli(expiryTime)); } } diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/token/TokenOption.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/token/TokenOption.java index 61d479bb36e8..6d7e857d689d 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/token/TokenOption.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/token/TokenOption.java @@ -18,13 +18,17 @@ package org.apache.hadoop.ozone.shell.token; import org.apache.hadoop.ozone.security.OzoneTokenIdentifier; +import org.apache.hadoop.security.Credentials; import org.apache.hadoop.security.token.Token; +import org.apache.hadoop.security.token.TokenIdentifier; import picocli.CommandLine; +import java.io.DataInputStream; +import java.io.DataOutputStream; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; /** * Option for token file. @@ -33,7 +37,7 @@ public class TokenOption { @CommandLine.Option(names = {"--token", "-t"}, description = "file containing encoded token", - defaultValue = "/tmp/token.txt", + defaultValue = "/tmp/ozone.token", showDefaultValue = CommandLine.Help.Visibility.ALWAYS) private File tokenFile; @@ -47,10 +51,30 @@ public boolean exists() { } public Token decode() throws IOException { - Token token = new Token<>(); - token.decodeFromUrlString(new String(Files.readAllBytes(tokenFile.toPath()), - StandardCharsets.UTF_8)); - return token; + Credentials creds = new Credentials(); + try (FileInputStream fis = new FileInputStream(tokenFile)) { + try (DataInputStream dis = new DataInputStream(fis)) { + creds.readTokenStorageStream(dis); + } + } + for (Token token: creds.getAllTokens()) { + if (token.getKind().equals(OzoneTokenIdentifier.KIND_NAME)) { + return (Token) token; + } + } + return null; } + public void persistToken(Token token) + throws IOException { + try (FileOutputStream fos = new FileOutputStream(tokenFile)) { + try (DataOutputStream dos = new DataOutputStream(fos)) { + Credentials ts = new Credentials(); + ts.addToken(token.getService(), token); + ts.writeTokenStorageToStream(dos); + System.out.println("Token persisted to " + tokenFile.toString() + + " successfully!"); + } + } + } } \ No newline at end of file