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 return SecureHadoopUser.createUserForTesting(conf, name, groups);
232 }
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250 public static void login(Configuration conf, String fileConfKey,
251 String principalConfKey, String localhost) throws IOException {
252 SecureHadoopUser.login(conf, fileConfKey, principalConfKey, localhost);
253 }
254
255
256
257
258
259
260
261 public static boolean isSecurityEnabled() {
262 return SecureHadoopUser.isSecurityEnabled();
263 }
264
265
266
267
268
269
270 public static boolean isHBaseSecurityEnabled(Configuration conf) {
271 return "kerberos".equalsIgnoreCase(conf.get(HBASE_SECURITY_CONF_KEY));
272 }
273
274
275
276
277
278
279
280
281 private static class SecureHadoopUser extends User {
282 private String shortName;
283
284 private SecureHadoopUser() throws IOException {
285 ugi = UserGroupInformation.getCurrentUser();
286 }
287
288 private SecureHadoopUser(UserGroupInformation ugi) {
289 this.ugi = ugi;
290 }
291
292 @Override
293 public String getShortName() {
294 if (shortName != null) return shortName;
295 try {
296 shortName = ugi.getShortUserName();
297 return shortName;
298 } catch (Exception e) {
299 throw new RuntimeException("Unexpected error getting user short name",
300 e);
301 }
302 }
303
304 @Override
305 public <T> T runAs(PrivilegedAction<T> action) {
306 return ugi.doAs(action);
307 }
308
309 @Override
310 public <T> T runAs(PrivilegedExceptionAction<T> action)
311 throws IOException, InterruptedException {
312 return ugi.doAs(action);
313 }
314
315 @Override
316 public void obtainAuthTokenForJob(Configuration conf, Job job)
317 throws IOException, InterruptedException {
318 try {
319 Class<?> c = Class.forName(
320 "org.apache.hadoop.hbase.security.token.TokenUtil");
321 Methods.call(c, null, "obtainTokenForJob",
322 new Class[]{Configuration.class, UserGroupInformation.class,
323 Job.class},
324 new Object[]{conf, ugi, job});
325 } catch (ClassNotFoundException cnfe) {
326 throw new RuntimeException("Failure loading TokenUtil class, "
327 +"is secure RPC available?", cnfe);
328 } catch (IOException ioe) {
329 throw ioe;
330 } catch (InterruptedException ie) {
331 throw ie;
332 } catch (RuntimeException re) {
333 throw re;
334 } catch (Exception e) {
335 throw new UndeclaredThrowableException(e,
336 "Unexpected error calling TokenUtil.obtainAndCacheToken()");
337 }
338 }
339
340 @Override
341 public void obtainAuthTokenForJob(JobConf job)
342 throws IOException, InterruptedException {
343 try {
344 Class<?> c = Class.forName(
345 "org.apache.hadoop.hbase.security.token.TokenUtil");
346 Methods.call(c, null, "obtainTokenForJob",
347 new Class[]{JobConf.class, UserGroupInformation.class},
348 new Object[]{job, ugi});
349 } catch (ClassNotFoundException cnfe) {
350 throw new RuntimeException("Failure loading TokenUtil class, "
351 +"is secure RPC available?", cnfe);
352 } catch (IOException ioe) {
353 throw ioe;
354 } catch (InterruptedException ie) {
355 throw ie;
356 } catch (RuntimeException re) {
357 throw re;
358 } catch (Exception e) {
359 throw new UndeclaredThrowableException(e,
360 "Unexpected error calling TokenUtil.obtainAndCacheToken()");
361 }
362 }
363
364
365 public static User createUserForTesting(Configuration conf,
366 String name, String[] groups) {
367 return new SecureHadoopUser(UserGroupInformation.createUserForTesting(name, groups));
368 }
369
370
371
372
373
374
375
376
377
378
379
380
381
382 public static void login(Configuration conf, String fileConfKey,
383 String principalConfKey, String localhost) throws IOException {
384 if (isSecurityEnabled()) {
385 SecurityUtil.login(conf, fileConfKey, principalConfKey, localhost);
386 }
387 }
388
389
390
391
392 public static boolean isSecurityEnabled() {
393 return UserGroupInformation.isSecurityEnabled();
394 }
395 }
396 }