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