1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 package org.apache.hadoop.hdfs.security.token.delegation;
19 
20 import java.net.URI;
21 import java.util.Collection;
22 
23 import org.apache.hadoop.classification.InterfaceAudience;
24 import org.apache.hadoop.conf.Configuration;
25 import org.apache.hadoop.hdfs.server.namenode.NameNode;
26 import org.apache.hadoop.io.Text;
27 import org.apache.hadoop.net.NetUtils;
28 import org.apache.hadoop.security.SecurityUtil;
29 import org.apache.hadoop.security.token.Token;
30 import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenSelector;
31 
32 /**
33  * A delegation token that is specialized for HDFS
34  */
35 @InterfaceAudience.Private
36 public class DelegationTokenSelector
37     extends AbstractDelegationTokenSelector<DelegationTokenIdentifier>{
38   public static final String SERVICE_NAME_KEY = "hdfs.service.host_";
39 
40   /**
41    * Select the delegation token for hdfs.  The port will be rewritten to
42    * the port of hdfs.service.host_$nnAddr, or the default rpc namenode port.
43    * This method should only be called by non-hdfs filesystems that do not
44    * use the rpc port to acquire tokens.  Ex. webhdfs, hftp
45    * @param nnUri of the remote namenode
46    * @param tokens as a collection
47    * @param conf hadoop configuration
48    * @return Token
49    */
selectToken( final URI nnUri, Collection<Token<?>> tokens, final Configuration conf)50   public Token<DelegationTokenIdentifier> selectToken(
51       final URI nnUri, Collection<Token<?>> tokens,
52       final Configuration conf) {
53     // this guesses the remote cluster's rpc service port.
54     // the current token design assumes it's the same as the local cluster's
55     // rpc port unless a config key is set.  there should be a way to automatic
56     // and correctly determine the value
57     Text serviceName = SecurityUtil.buildTokenService(nnUri);
58     final String nnServiceName = conf.get(SERVICE_NAME_KEY + serviceName);
59 
60     int nnRpcPort = NameNode.DEFAULT_PORT;
61     if (nnServiceName != null) {
62       nnRpcPort = NetUtils.createSocketAddr(nnServiceName, nnRpcPort).getPort();
63     }
64     // use original hostname from the uri to avoid unintentional host resolving
65     serviceName = SecurityUtil.buildTokenService(
66     		NetUtils.createSocketAddrForHost(nnUri.getHost(), nnRpcPort));
67 
68     return selectToken(serviceName, tokens);
69   }
70 
DelegationTokenSelector()71   public DelegationTokenSelector() {
72     super(DelegationTokenIdentifier.HDFS_DELEGATION_KIND);
73   }
74 }
75