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 19 package org.apache.hadoop.hdfs.security; 20 21 22 23 import java.io.ByteArrayInputStream; 24 import java.io.DataInputStream; 25 import java.io.IOException; 26 import java.net.InetAddress; 27 import java.net.NetworkInterface; 28 import java.security.PrivilegedExceptionAction; 29 import java.util.ArrayList; 30 import java.util.Enumeration; 31 32 import org.apache.commons.logging.Log; 33 import org.apache.commons.logging.LogFactory; 34 import org.apache.hadoop.conf.Configuration; 35 import org.apache.hadoop.fs.FSDataOutputStream; 36 import org.apache.hadoop.fs.FileStatus; 37 import org.apache.hadoop.fs.FileSystem; 38 import org.apache.hadoop.fs.Path; 39 import org.apache.hadoop.fs.permission.FsPermission; 40 import org.apache.hadoop.hdfs.DFSConfigKeys; 41 import org.apache.hadoop.hdfs.HdfsConfiguration; 42 import org.apache.hadoop.hdfs.MiniDFSCluster; 43 import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier; 44 import org.apache.hadoop.hdfs.web.WebHdfsFileSystem; 45 import org.apache.hadoop.hdfs.web.WebHdfsTestUtil; 46 import org.apache.hadoop.security.TestDoAsEffectiveUser; 47 import org.apache.hadoop.security.UserGroupInformation; 48 import org.apache.hadoop.security.authorize.DefaultImpersonationProvider; 49 import org.apache.hadoop.security.authorize.ProxyUsers; 50 import org.apache.hadoop.security.token.Token; 51 import org.junit.AfterClass; 52 import org.junit.Assert; 53 import org.junit.BeforeClass; 54 import org.junit.Test; 55 import org.mockito.internal.util.reflection.Whitebox; 56 57 public class TestDelegationTokenForProxyUser { 58 private static MiniDFSCluster cluster; 59 private static Configuration config; 60 final private static String GROUP1_NAME = "group1"; 61 final private static String GROUP2_NAME = "group2"; 62 final private static String[] GROUP_NAMES = new String[] { GROUP1_NAME, 63 GROUP2_NAME }; 64 final private static String REAL_USER = "RealUser"; 65 final private static String PROXY_USER = "ProxyUser"; 66 private static UserGroupInformation ugi; 67 private static UserGroupInformation proxyUgi; 68 69 private static final Log LOG = LogFactory.getLog(TestDoAsEffectiveUser.class); 70 configureSuperUserIPAddresses(Configuration conf, String superUserShortName)71 private static void configureSuperUserIPAddresses(Configuration conf, 72 String superUserShortName) throws IOException { 73 ArrayList<String> ipList = new ArrayList<String>(); 74 Enumeration<NetworkInterface> netInterfaceList = NetworkInterface 75 .getNetworkInterfaces(); 76 while (netInterfaceList.hasMoreElements()) { 77 NetworkInterface inf = netInterfaceList.nextElement(); 78 Enumeration<InetAddress> addrList = inf.getInetAddresses(); 79 while (addrList.hasMoreElements()) { 80 InetAddress addr = addrList.nextElement(); 81 ipList.add(addr.getHostAddress()); 82 } 83 } 84 StringBuilder builder = new StringBuilder(); 85 for (String ip : ipList) { 86 builder.append(ip); 87 builder.append(','); 88 } 89 builder.append("127.0.1.1,"); 90 builder.append(InetAddress.getLocalHost().getCanonicalHostName()); 91 LOG.info("Local Ip addresses: " + builder.toString()); 92 conf.setStrings(DefaultImpersonationProvider.getTestProvider(). 93 getProxySuperuserIpConfKey(superUserShortName), 94 builder.toString()); 95 } 96 97 @BeforeClass setUp()98 public static void setUp() throws Exception { 99 config = new HdfsConfiguration(); 100 config.setBoolean(DFSConfigKeys.DFS_WEBHDFS_ENABLED_KEY, true); 101 config.setLong( 102 DFSConfigKeys.DFS_NAMENODE_DELEGATION_TOKEN_MAX_LIFETIME_KEY, 10000); 103 config.setLong( 104 DFSConfigKeys.DFS_NAMENODE_DELEGATION_TOKEN_RENEW_INTERVAL_KEY, 5000); 105 config.setStrings(DefaultImpersonationProvider.getTestProvider(). 106 getProxySuperuserGroupConfKey(REAL_USER), 107 "group1"); 108 config.setBoolean( 109 DFSConfigKeys.DFS_NAMENODE_DELEGATION_TOKEN_ALWAYS_USE_KEY, true); 110 configureSuperUserIPAddresses(config, REAL_USER); 111 FileSystem.setDefaultUri(config, "hdfs://localhost:" + "0"); 112 cluster = new MiniDFSCluster.Builder(config).build(); 113 cluster.waitActive(); 114 ProxyUsers.refreshSuperUserGroupsConfiguration(config); 115 ugi = UserGroupInformation.createRemoteUser(REAL_USER); 116 proxyUgi = UserGroupInformation.createProxyUserForTesting(PROXY_USER, ugi, 117 GROUP_NAMES); 118 } 119 120 @AfterClass tearDown()121 public static void tearDown() throws Exception { 122 if(cluster!=null) { 123 cluster.shutdown(); 124 } 125 } 126 127 @Test(timeout=20000) testDelegationTokenWithRealUser()128 public void testDelegationTokenWithRealUser() throws IOException { 129 try { 130 Token<?>[] tokens = proxyUgi 131 .doAs(new PrivilegedExceptionAction<Token<?>[]>() { 132 @Override 133 public Token<?>[] run() throws IOException { 134 return cluster.getFileSystem().addDelegationTokens("RenewerUser", null); 135 } 136 }); 137 DelegationTokenIdentifier identifier = new DelegationTokenIdentifier(); 138 byte[] tokenId = tokens[0].getIdentifier(); 139 identifier.readFields(new DataInputStream(new ByteArrayInputStream( 140 tokenId))); 141 Assert.assertEquals(identifier.getUser().getUserName(), PROXY_USER); 142 Assert.assertEquals(identifier.getUser().getRealUser().getUserName(), 143 REAL_USER); 144 } catch (InterruptedException e) { 145 //Do Nothing 146 } 147 } 148 149 @Test(timeout=5000) testWebHdfsDoAs()150 public void testWebHdfsDoAs() throws Exception { 151 WebHdfsTestUtil.LOG.info("START: testWebHdfsDoAs()"); 152 WebHdfsTestUtil.LOG.info("ugi.getShortUserName()=" + ugi.getShortUserName()); 153 final WebHdfsFileSystem webhdfs = WebHdfsTestUtil.getWebHdfsFileSystemAs(ugi, config, WebHdfsFileSystem.SCHEME); 154 155 final Path root = new Path("/"); 156 cluster.getFileSystem().setPermission(root, new FsPermission((short)0777)); 157 158 Whitebox.setInternalState(webhdfs, "ugi", proxyUgi); 159 160 { 161 Path responsePath = webhdfs.getHomeDirectory(); 162 WebHdfsTestUtil.LOG.info("responsePath=" + responsePath); 163 Assert.assertEquals(webhdfs.getUri() + "/user/" + PROXY_USER, responsePath.toString()); 164 } 165 166 final Path f = new Path("/testWebHdfsDoAs/a.txt"); 167 { 168 FSDataOutputStream out = webhdfs.create(f); 169 out.write("Hello, webhdfs user!".getBytes()); 170 out.close(); 171 172 final FileStatus status = webhdfs.getFileStatus(f); 173 WebHdfsTestUtil.LOG.info("status.getOwner()=" + status.getOwner()); 174 Assert.assertEquals(PROXY_USER, status.getOwner()); 175 } 176 177 { 178 final FSDataOutputStream out = webhdfs.append(f); 179 out.write("\nHello again!".getBytes()); 180 out.close(); 181 182 final FileStatus status = webhdfs.getFileStatus(f); 183 WebHdfsTestUtil.LOG.info("status.getOwner()=" + status.getOwner()); 184 WebHdfsTestUtil.LOG.info("status.getLen() =" + status.getLen()); 185 Assert.assertEquals(PROXY_USER, status.getOwner()); 186 } 187 } 188 } 189