Skip to content

Commit e3d76d0

Browse files
author
Raymond Lam
authored
[hadoop] LIHADOOP-76132 : Evolve the BundledTokenIdentifier to include SPIFFE tokens (apache#458)
1 parent df81929 commit e3d76d0

File tree

3 files changed

+114
-32
lines changed

3 files changed

+114
-32
lines changed

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/token/delegation/BundledTokenIdentifier.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,7 @@ public interface BundledTokenIdentifier {
2020

2121
// The bundled information for additional tokens.
2222
Token[] getInnerTokens();
23+
24+
// The SPIFFE tokens
25+
Token[] getSPIFFETokens();
2326
}

hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/security/token/delegation/BundledDelegationTokenIdentifier.java

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ public class BundledDelegationTokenIdentifier extends DelegationTokenIdentifier
2323
implements BundledTokenIdentifier {
2424

2525
// The current VERSION of the token.
26-
private static final byte VERSION = 0;
26+
private static final byte VERSION = 1;
27+
28+
// The original serde implementation of this identifier was un-versioned.
29+
// This denotes the default version for un-versioned tokens.
30+
private static final byte BASE_VERSION = 0;
2731

2832
// The designated main password.
2933
// This will be empty (byte[0]) if deserialization fails to read any content
@@ -45,22 +49,28 @@ public class BundledDelegationTokenIdentifier extends DelegationTokenIdentifier
4549
// content for the tokenVersion.
4650
private byte tokenVersion;
4751

48-
// The original serde implementation of this identifier was un-versioned.
49-
// This denotes the default version for un-versioned tokens.
50-
private static final byte BASE_VERSION = 0;
52+
// The list of SPIFFE tokens.
53+
private Token[] spiffeTokens;
5154

5255
public BundledDelegationTokenIdentifier() {
5356
super();
5457
}
5558

5659
public BundledDelegationTokenIdentifier(Token<?> mainToken,
5760
Token<AbstractDelegationTokenIdentifier>[] tokens) throws IOException {
61+
this(mainToken, tokens, new Token[0]);
62+
}
63+
64+
public BundledDelegationTokenIdentifier(Token<?> mainToken,
65+
Token<AbstractDelegationTokenIdentifier>[] tokens,
66+
Token<SPIFFEDelegationTokenIdentifier>[] spiffeTokens) throws IOException {
5867
this((AbstractDelegationTokenIdentifier) mainToken.decodeIdentifier(),
59-
mainToken.getPassword(), tokens);
68+
mainToken.getPassword(), tokens, spiffeTokens);
6069
}
6170

6271
public BundledDelegationTokenIdentifier(AbstractDelegationTokenIdentifier mainTokenId,
63-
byte[] mainPassword, Token<AbstractDelegationTokenIdentifier>[] tokens) throws IOException {
72+
byte[] mainPassword, Token<AbstractDelegationTokenIdentifier>[] tokens,
73+
Token<SPIFFEDelegationTokenIdentifier>[] spiffeTokens) throws IOException {
6474
super(mainTokenId.getOwner(), mainTokenId.getRenewer(), mainTokenId.getRealUser());
6575
// Set the attributes from the main tokenIdentifier, which are expected by the
6676
// DelegationTokenIdentifier class.
@@ -81,6 +91,12 @@ public BundledDelegationTokenIdentifier(AbstractDelegationTokenIdentifier mainTo
8191
this.innerTokens = tokens;
8292

8393
this.tokenVersion = VERSION;
94+
95+
if (spiffeTokens == null) {
96+
spiffeTokens = new Token[0];
97+
}
98+
99+
this.spiffeTokens = spiffeTokens;
84100
}
85101

86102
@Override
@@ -98,6 +114,11 @@ public void write(DataOutput out) throws IOException {
98114
}
99115

100116
out.writeByte(tokenVersion);
117+
118+
WritableUtils.writeVInt(out, this.spiffeTokens.length);
119+
for (Token spiffeToken : this.spiffeTokens) {
120+
spiffeToken.write(out);
121+
}
101122
}
102123

103124
@Override
@@ -138,6 +159,18 @@ public void readFields(DataInput in) throws IOException {
138159
this.innerTokens = new Token[0];
139160
this.tokenVersion = BASE_VERSION;
140161
}
162+
163+
if (this.tokenVersion < 1) {
164+
this.spiffeTokens = new Token[0];
165+
} else {
166+
int spiffeTokenLength = WritableUtils.readVInt(in);
167+
this.spiffeTokens = new Token[spiffeTokenLength];
168+
for (int i = 0; i < spiffeTokenLength; ++i) {
169+
Token spiffeToken = new Token();
170+
spiffeToken.readFields(in);
171+
this.spiffeTokens[i] = spiffeToken;
172+
}
173+
}
141174
}
142175

143176
@Override
@@ -159,4 +192,9 @@ public byte[] getMainPassword() {
159192
public Token[] getInnerTokens() {
160193
return this.innerTokens;
161194
}
195+
196+
@Override
197+
public Token[] getSPIFFETokens() {
198+
return this.spiffeTokens;
199+
}
162200
}

hadoop-hdfs-project/hadoop-hdfs-client/src/test/java/org/apache/hadoop/hdfs/security/token/delegation/TestBundledDelegationTokenIdentifier.java

Lines changed: 67 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,10 @@
1515
public class TestBundledDelegationTokenIdentifier {
1616
@Test
1717
public void testBundledTokenSerialization() throws Exception {
18-
// Create tokenIdentifier with bundled tokens and write to stream.
19-
BundledDelegationTokenIdentifier bundledTokenId1 = createTestBundledTokenId();
20-
DataOutputBuffer out = new DataOutputBuffer();
21-
bundledTokenId1.write(out);
22-
23-
// Read as bundledTokenIdentifier from stream.
24-
BundledDelegationTokenIdentifier bundledTokenId2 = new BundledDelegationTokenIdentifier();
25-
readDelegationTokenIdentifier(bundledTokenId2, out);
26-
27-
// Validate that DelegationTokenInformation attributes are deserialized correctly.
28-
assertEquals(bundledTokenId1, bundledTokenId2);
29-
30-
Token[] innerTokens1 = bundledTokenId1.getInnerTokens();
31-
Token[] innerTokens2 = bundledTokenId2.getInnerTokens();
32-
33-
// Validate that bundled token information was deserialized correctly.
34-
assertEquals(innerTokens1.length, innerTokens2.length);
35-
for (int i = 0; i < innerTokens1.length; i++) {
36-
assertEquals(innerTokens1[i].decodeIdentifier(), innerTokens2[i].decodeIdentifier());
37-
assertArrayEquals(innerTokens1[i].getPassword(), innerTokens2[i].getPassword());
38-
assertEquals(innerTokens1[i].getService(), innerTokens2[i].getService());
39-
}
18+
assertBundledDelegationTokensEquals(3, 0);
19+
assertBundledDelegationTokensEquals(0, 1);
20+
assertBundledDelegationTokensEquals(3, 1);
21+
assertBundledDelegationTokensEquals(3, 3);
4022
}
4123

4224
@Test
@@ -78,14 +60,29 @@ public void testBundledTokenForwardsCompatible() throws Exception {
7860
}
7961

8062
private BundledDelegationTokenIdentifier createTestBundledTokenId() throws IOException {
81-
int tokensLength = 3;
82-
Token<AbstractDelegationTokenIdentifier>[] allTokens = new Token[tokensLength];
83-
for (int i = 0; i < tokensLength; i++) {
63+
return createTestBundledTokenId(3, 0);
64+
}
65+
66+
private BundledDelegationTokenIdentifier createTestBundledTokenId(
67+
int hdfsTokensLength,
68+
int spiffeTokenLength) throws IOException {
69+
Token<AbstractDelegationTokenIdentifier> mainToken = createTestToken(1);
70+
71+
Token<AbstractDelegationTokenIdentifier>[] allTokens = new Token[hdfsTokensLength];
72+
for (int i = 0; i < hdfsTokensLength; i++) {
8473
Token<AbstractDelegationTokenIdentifier> token1 = createTestToken(i + 1);
8574
allTokens[i] = token1;
8675
}
8776

88-
return new BundledDelegationTokenIdentifier(allTokens[0], allTokens);
77+
Token<SPIFFEDelegationTokenIdentifier>[] spiffeTokens = new Token[spiffeTokenLength];
78+
for (int i = 0; i < spiffeTokenLength; ++i) {
79+
Token<SPIFFEDelegationTokenIdentifier> spiffeToken =
80+
createTestSPIFFEToken(i + 1);
81+
spiffeTokens[i] = spiffeToken;
82+
}
83+
84+
return new BundledDelegationTokenIdentifier(
85+
mainToken, allTokens, spiffeTokens);
8986
}
9087

9188
private Token<AbstractDelegationTokenIdentifier> createTestToken(int id) {
@@ -102,10 +99,54 @@ private Token<AbstractDelegationTokenIdentifier> createTestToken(int id) {
10299
new Text("HDFS_DELEGATION_TOKEN"), new Text("service_" + id));
103100
}
104101

102+
private Token<SPIFFEDelegationTokenIdentifier> createTestSPIFFEToken(int id) {
103+
SPIFFEDelegationTokenIdentifier identifier =
104+
new SPIFFEDelegationTokenIdentifier("header_" + id, "payload_" + id);
105+
return new Token<>(identifier.getBytes(), ("password_" + id).getBytes(),
106+
SPIFFEDelegationTokenIdentifier.SPIFFE_DELEGATION_KIND, null);
107+
}
108+
105109
private void readDelegationTokenIdentifier(DelegationTokenIdentifier tokenId,
106110
DataOutputBuffer out) throws IOException {
107111
DataInputBuffer in = new DataInputBuffer();
108112
in.reset(out.getData(), out.getLength());
109113
tokenId.readFields(in);
110114
}
115+
116+
private void assertBundledDelegationTokensEquals(
117+
int expectedNumHdfsTokens, int expectedNumSpiffeTokens) throws IOException {
118+
119+
BundledDelegationTokenIdentifier bundledTokenId1 =
120+
createTestBundledTokenId(expectedNumHdfsTokens, expectedNumSpiffeTokens);
121+
DataOutputBuffer out = new DataOutputBuffer();
122+
bundledTokenId1.write(out);
123+
124+
// Read as bundledTokenIdentifier from stream.
125+
BundledDelegationTokenIdentifier bundledTokenId2 = new BundledDelegationTokenIdentifier();
126+
readDelegationTokenIdentifier(bundledTokenId2, out);
127+
128+
// Validate that DelegationTokenInformation attributes are deserialized correctly.
129+
assertEquals(bundledTokenId1, bundledTokenId2);
130+
131+
Token[] innerTokens1 = bundledTokenId1.getInnerTokens();
132+
Token[] innerTokens2 = bundledTokenId2.getInnerTokens();
133+
134+
// Validate that bundled token information was deserialized correctly.
135+
assertEquals(innerTokens1.length, innerTokens2.length);
136+
for (int i = 0; i < innerTokens1.length; i++) {
137+
assertEquals(innerTokens1[i].getKind(), innerTokens2[i].getKind());
138+
assertEquals(innerTokens1[i].decodeIdentifier(), innerTokens2[i].decodeIdentifier());
139+
assertArrayEquals(innerTokens1[i].getPassword(), innerTokens2[i].getPassword());
140+
assertEquals(innerTokens1[i].getService(), innerTokens2[i].getService());
141+
}
142+
143+
Token[] spiffeTokens1 = bundledTokenId1.getSPIFFETokens();
144+
Token[] spiffeTokens2 = bundledTokenId2.getSPIFFETokens();
145+
146+
assertEquals(spiffeTokens1.length, spiffeTokens2.length);
147+
for (int i = 0; i < spiffeTokens1.length; ++i) {
148+
assertEquals(spiffeTokens1[i], spiffeTokens2[i]);
149+
assertEquals(spiffeTokens1[i].decodeIdentifier(), spiffeTokens2[i].decodeIdentifier());
150+
}
151+
}
111152
}

0 commit comments

Comments
 (0)