1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.security;
21
22 import java.io.IOException;
23 import java.lang.reflect.UndeclaredThrowableException;
24 import java.security.PrivilegedAction;
25 import java.security.PrivilegedExceptionAction;
26 import java.util.Collection;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.hadoop.conf.Configuration;
31 import org.apache.hadoop.hbase.classification.InterfaceAudience;
32 import org.apache.hadoop.hbase.classification.InterfaceStability;
33 import org.apache.hadoop.hbase.util.Methods;
34 import org.apache.hadoop.mapred.JobConf;
35 import org.apache.hadoop.mapreduce.Job;
36 import org.apache.hadoop.security.SecurityUtil;
37 import org.apache.hadoop.security.UserGroupInformation;
38 import org.apache.hadoop.security.token.Token;
39 import org.apache.hadoop.security.token.TokenIdentifier;
40
41
42
43
44
45
46
47
48
49
50
51
52 @InterfaceAudience.Public
53 @InterfaceStability.Stable
54 public abstract class User {
55 public static final String HBASE_SECURITY_CONF_KEY =
56 "hbase.security.authentication";
57 public static final String HBASE_SECURITY_AUTHORIZATION_CONF_KEY =
58 "hbase.security.authorization";
59
60 private static Log LOG = LogFactory.getLog(User.class);
61
62 protected UserGroupInformation ugi;
63
64 public UserGroupInformation getUGI() {
65 return ugi;
66 }
67
68
69
70
71
72
73
74 public String getName() {
75 return ugi.getUserName();
76 }
77
78
79
80
81
82
83 public String[] getGroupNames() {
84 return ugi.getGroupNames();
85 }
86
87
88
89
90
91
92
93 public abstract String getShortName();
94
95
96
97
98 public abstract <T> T runAs(PrivilegedAction<T> action);
99
100
101
102
103 public abstract <T> T runAs(PrivilegedExceptionAction<T> action)
104 throws IOException, InterruptedException;
105
106
107
108
109
110
111
112
113
114 @Deprecated
115 public abstract void obtainAuthTokenForJob(Configuration conf, Job job)
116 throws IOException, InterruptedException;
117
118
119
120
121
122
123
124
125
126 @Deprecated
127 public abstract void obtainAuthTokenForJob(JobConf job)
128 throws IOException, InterruptedException;
129
130
131
132
133
134
135
136
137
138 public Token<?> getToken(String kind, String service) throws IOException {
139 for (Token<?> token : ugi.getTokens()) {
140 if (token.getKind().toString().equals(kind) &&
141 (service != null && token.getService().toString().equals(service))) {
142 return token;
143 }
144 }
145 return null;
146 }
147
148
149
150
151 public Collection<Token<? extends TokenIdentifier>> getTokens() {
152 return ugi.getTokens();
153 }
154
155
156
157
158
159
160 public void addToken(Token<? extends TokenIdentifier> token) {
161 ugi.addToken(token);
162 }
163
164 @Override
165 public boolean equals(Object o) {
166 if (this == o) {
167 return true;
168 }
169 if (o == null || getClass() != o.getClass()) {
170 return false;
171 }
172 return ugi.equals(((User) o).ugi);
173 }
174
175 @Override
176 public int hashCode() {
177 return ugi.hashCode();
178 }
179
180 @Override
181 public String toString() {
182 return ugi.toString();
183 }
184
185
186
187
188 public static User getCurrent() throws IOException {
189 User user = new SecureHadoopUser();
190 if (user.getUGI() == null) {
191 return null;
192 }
193 return user;
194 }
195
196
197
198
199
200
201
202
203 @SuppressWarnings({ "rawtypes", "unchecked" })
204 public static <T> T runAsLoginUser(PrivilegedExceptionAction<T> action) throws IOException {
205 return doAsUser(UserGroupInformation.getLoginUser(), action);
206 }
207
208 private static <T> T doAsUser(UserGroupInformation ugi,
209 PrivilegedExceptionAction<T> action) throws IOException {
210 try {
211 return ugi.doAs(action);
212 } catch (InterruptedException ie) {
213 throw new IOException(ie);
214 }
215 }
216
217
218
219
220
221
222 public static User create(UserGroupInformation ugi) {
223 if (ugi == null) {
224 return null;
225 }
226 return new SecureHadoopUser(ugi);
227 }
228
229
230
231
232
233
234
235 public static User createUserForTesting(Configuration conf,
236 String name, String[] groups) {
237 User userForTesting = SecureHadoopUser.createUserForTesting(conf, name, groups);
238 return userForTesting;
239 }
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257 public static void login(Configuration conf, String fileConfKey,
258 String principalConfKey, String localhost) throws IOException {
259 SecureHadoopUser.login(conf, fileConfKey, principalConfKey, localhost);
260 }
261
262
263
264
265
266
267
268 public static boolean isSecurityEnabled() {
269 return SecureHadoopUser.isSecurityEnabled();
270 }
271
272
273
274
275
276
277 public static boolean isHBaseSecurityEnabled(Configuration conf) {
278 return "kerberos".equalsIgnoreCase(conf.get(HBASE_SECURITY_CONF_KEY));
279 }
280
281
282
283
284
285
286
287
288 private static class SecureHadoopUser extends User {
289 private String shortName;
290
291 private SecureHadoopUser() throws IOException {
292 ugi = UserGroupInformation.getCurrentUser();
293 }
294
295 private SecureHadoopUser(UserGroupInformation ugi) {
296 this.ugi = ugi;
297 }
298
299 @Override
300 public String getShortName() {
301 if (shortName != null) return shortName;
302 try {
303 shortName = ugi.getShortUserName();
304 return shortName;
305 } catch (Exception e) {
306 throw new RuntimeException("Unexpected error getting user short name",
307 e);
308 }
309 }
310
311 @Override
312 public <T> T runAs(PrivilegedAction<T> action) {
313 return ugi.doAs(action);
314 }
315
316 @Override
317 public <T> T runAs(PrivilegedExceptionAction<T> action)
318 throws IOException, InterruptedException {
319 return ugi.doAs(action);
320 }
321
322 @Override
323 public void obtainAuthTokenForJob(Configuration conf, Job job)
324 throws IOException, InterruptedException {
325 try {
326 Class<?> c = Class.forName(
327 "org.apache.hadoop.hbase.security.token.TokenUtil");
328 Methods.call(c, null, "obtainTokenForJob",
329 new Class[]{Configuration.class, UserGroupInformation.class,
330 Job.class},
331 new Object[]{conf, ugi, job});
332 } catch (ClassNotFoundException cnfe) {
333 throw new RuntimeException("Failure loading TokenUtil class, "
334 +"is secure RPC available?", cnfe);
335 } catch (IOException ioe) {
336 throw ioe;
337 } catch (InterruptedException ie) {
338 throw ie;
339 } catch (RuntimeException re) {
340 throw re;
341 } catch (Exception e) {
342 throw new UndeclaredThrowableException(e,
343 "Unexpected error calling TokenUtil.obtainAndCacheToken()");
344 }
345 }
346
347 @Override
348 public void obtainAuthTokenForJob(JobConf job)
349 throws IOException, InterruptedException {
350 try {
351 Class<?> c = Class.forName(
352 "org.apache.hadoop.hbase.security.token.TokenUtil");
353 Methods.call(c, null, "obtainTokenForJob",
354 new Class[]{JobConf.class, UserGroupInformation.class},
355 new Object[]{job, ugi});
356 } catch (ClassNotFoundException cnfe) {
357 throw new RuntimeException("Failure loading TokenUtil class, "
358 +"is secure RPC available?", cnfe);
359 } catch (IOException ioe) {
360 throw ioe;
361 } catch (InterruptedException ie) {
362 throw ie;
363 } catch (RuntimeException re) {
364 throw re;
365 } catch (Exception e) {
366 throw new UndeclaredThrowableException(e,
367 "Unexpected error calling TokenUtil.obtainAndCacheToken()");
368 }
369 }
370
371
372 public static User createUserForTesting(Configuration conf,
373 String name, String[] groups) {
374 return new SecureHadoopUser(UserGroupInformation.createUserForTesting(name, groups));
375 }
376
377
378
379
380
381
382
383
384
385
386
387
388
389 public static void login(Configuration conf, String fileConfKey,
390 String principalConfKey, String localhost) throws IOException {
391 if (isSecurityEnabled()) {
392 SecurityUtil.login(conf, fileConfKey, principalConfKey, localhost);
393 }
394 }
395
396
397
398
399 public static boolean isSecurityEnabled() {
400 return UserGroupInformation.isSecurityEnabled();
401 }
402 }
403 }