Skip to content

Commit 026dce5

Browse files
authored
HDFS-15465. Support WebHDFS accesses to the data stored in secure Datanode through insecure Namenode. (#2135)
1 parent 60a2546 commit 026dce5

File tree

5 files changed

+53
-5
lines changed

5 files changed

+53
-5
lines changed

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/web/webhdfs/DataNodeUGIProvider.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,12 @@ UserGroupInformation ugi() throws IOException {
7272
UserGroupInformation ugi;
7373

7474
try {
75-
if (UserGroupInformation.isSecurityEnabled()) {
76-
final Token<DelegationTokenIdentifier> token = params.delegationToken();
75+
final Token<DelegationTokenIdentifier> token = params.delegationToken();
7776

77+
// Create nonTokenUGI when token is null regardless of security.
78+
// This makes it possible to access the data stored in secure DataNode
79+
// through insecure Namenode.
80+
if (UserGroupInformation.isSecurityEnabled() && token != null) {
7881
ugi = ugiCache.get(buildTokenCacheKey(token),
7982
new Callable<UserGroupInformation>() {
8083
@Override
@@ -134,7 +137,8 @@ private String buildNonTokenCacheKey(String doAsUserFromQuery,
134137
return key;
135138
}
136139

137-
private UserGroupInformation nonTokenUGI(String usernameFromQuery,
140+
@VisibleForTesting
141+
UserGroupInformation nonTokenUGI(String usernameFromQuery,
138142
String doAsUserFromQuery, String remoteUser) throws IOException {
139143

140144
UserGroupInformation ugi = UserGroupInformation

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/web/webhdfs/ParameterParser.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ boolean noredirect() {
123123

124124
Token<DelegationTokenIdentifier> delegationToken() throws IOException {
125125
String delegation = param(DelegationParam.NAME);
126+
if (delegation == null) {
127+
return null;
128+
}
126129
final Token<DelegationTokenIdentifier> token = new
127130
Token<DelegationTokenIdentifier>();
128131
token.decodeFromUrlString(delegation);

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/web/webhdfs/WebHdfsHandler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,8 +335,8 @@ private static void writeContinueHeader(ChannelHandlerContext ctx) {
335335
}
336336

337337
private void injectToken() throws IOException {
338-
if (UserGroupInformation.isSecurityEnabled()) {
339-
Token<DelegationTokenIdentifier> token = params.delegationToken();
338+
Token<DelegationTokenIdentifier> token = params.delegationToken();
339+
if (UserGroupInformation.isSecurityEnabled() && token != null) {
340340
token.setKind(HDFS_DELEGATION_KIND);
341341
ugi.addToken(token);
342342
}

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/web/webhdfs/TestDataNodeUGIProvider.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
import static org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod.KERBEROS;
2222
import static org.mockito.Mockito.mock;
23+
import static org.mockito.Mockito.spy;
24+
import static org.mockito.Mockito.verify;
2325
import io.netty.handler.codec.http.QueryStringDecoder;
2426

2527
import java.io.IOException;
@@ -31,6 +33,7 @@
3133
import org.apache.hadoop.hdfs.DFSConfigKeys;
3234
import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier;
3335
import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenSecretManager;
36+
import org.apache.hadoop.hdfs.server.common.JspHelper;
3437
import org.apache.hadoop.hdfs.server.namenode.FSNamesystem;
3538
import org.apache.hadoop.hdfs.web.WebHdfsConstants;
3639
import org.apache.hadoop.hdfs.web.WebHdfsFileSystem;
@@ -186,6 +189,35 @@ public void testUGICacheInSecure() throws Exception {
186189
ugi11, url22);
187190
}
188191

192+
@Test
193+
public void testUGINullTokenSecure() throws IOException {
194+
SecurityUtil.setAuthenticationMethod(KERBEROS, conf);
195+
UserGroupInformation.setConfiguration(conf);
196+
197+
String uri1 = WebHdfsFileSystem.PATH_PREFIX
198+
+ PATH
199+
+ "?op=OPEN"
200+
+ Param.toSortedString("&", new OffsetParam((long) OFFSET),
201+
new LengthParam((long) LENGTH), new UserParam("root"));
202+
203+
ParameterParser params = new ParameterParser(
204+
new QueryStringDecoder(URI.create(uri1)), conf);
205+
206+
DataNodeUGIProvider ugiProvider = new DataNodeUGIProvider(params);
207+
208+
String usernameFromQuery = params.userName();
209+
String doAsUserFromQuery = params.doAsUser();
210+
String remoteUser = usernameFromQuery == null ? JspHelper
211+
.getDefaultWebUserName(params.conf())
212+
: usernameFromQuery;
213+
214+
DataNodeUGIProvider spiedUGIProvider = spy(ugiProvider);
215+
spiedUGIProvider.ugi();
216+
217+
verify(spiedUGIProvider).nonTokenUGI(usernameFromQuery, doAsUserFromQuery,
218+
remoteUser);
219+
}
220+
189221
/**
190222
* Wait for expiration of entries from the UGI cache. We need to be careful
191223
* not to touch the entries in the cache while we're waiting for expiration.

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/web/webhdfs/TestParameterParser.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ public void testDeserializeHAToken() throws IOException {
5555
Assert.assertTrue(HAUtilClient.isTokenForLogicalUri(tok2));
5656
}
5757

58+
@Test
59+
public void testNullToken() throws IOException {
60+
Configuration conf = new Configuration();
61+
QueryStringDecoder decoder = new QueryStringDecoder(
62+
WebHdfsHandler.WEBHDFS_PREFIX + "/test");
63+
ParameterParser testParser = new ParameterParser(decoder, conf);
64+
Assert.assertNull(testParser.delegationToken());
65+
}
66+
5867
@Test
5968
public void testDecodePath() {
6069
final String ESCAPED_PATH = "/test%25+1%26%3Dtest?op=OPEN&foo=bar";

0 commit comments

Comments
 (0)