18
18
*/
19
19
package org .apache .hadoop .hbase .thrift ;
20
20
21
+ import java .io .File ;
21
22
import java .nio .ByteBuffer ;
22
23
import java .nio .charset .CharacterCodingException ;
23
24
import java .nio .charset .Charset ;
24
25
import java .nio .charset .CharsetDecoder ;
26
+ import java .security .Principal ;
25
27
import java .security .PrivilegedExceptionAction ;
26
28
import java .util .ArrayList ;
27
29
import java .util .Base64 ;
28
30
import java .util .HashMap ;
31
+ import java .util .HashSet ;
29
32
import java .util .List ;
30
33
import java .util .Map ;
34
+ import java .util .Set ;
31
35
import java .util .SortedMap ;
32
36
import java .util .TreeMap ;
33
37
import javax .security .auth .Subject ;
38
+ import javax .security .auth .kerberos .KerberosPrincipal ;
34
39
import javax .security .auth .login .AppConfigurationEntry ;
35
40
import javax .security .auth .login .Configuration ;
36
41
import javax .security .auth .login .LoginContext ;
@@ -68,11 +73,13 @@ public class HttpDoAsClient {
68
73
private static boolean secure = false ;
69
74
static protected String doAsUser = null ;
70
75
static protected String principal = null ;
76
+ static protected String keyTab = null ;
71
77
72
78
public static void main (String [] args ) throws Exception {
73
- if (args .length < 3 || args .length > 4 ) {
79
+ if (args .length < 3 || args .length > 6 ) {
74
80
System .out .println ("Invalid arguments!" );
75
- System .out .println ("Usage: HttpDoAsClient host port doAsUserName [security=true]" );
81
+ System .out .println (
82
+ "Usage: HttpDoAsClient host port doAsUserName [security=true] [principal] [keytab]" );
76
83
System .exit (-1 );
77
84
}
78
85
@@ -81,7 +88,16 @@ public static void main(String[] args) throws Exception {
81
88
doAsUser = args [2 ];
82
89
if (args .length > 3 ) {
83
90
secure = Boolean .parseBoolean (args [3 ]);
84
- principal = getSubject ().getPrincipals ().iterator ().next ().getName ();
91
+ if (args .length > 4 ) {
92
+ principal = args [4 ];
93
+ keyTab = args [5 ];
94
+ if (!new File (keyTab ).exists ()) {
95
+ System .err .printf ("ERROR: KeyTab File %s not found %n" , keyTab );
96
+ System .exit (-1 );
97
+ }
98
+ } else {
99
+ principal = getSubject ().getPrincipals ().iterator ().next ().getName ();
100
+ }
85
101
}
86
102
87
103
final HttpDoAsClient client = new HttpDoAsClient ();
@@ -252,31 +268,66 @@ static Subject getSubject() throws Exception {
252
268
* To authenticate the DemoClient, kinit should be invoked ahead.
253
269
* Here we try to get the Kerberos credential from the ticket cache.
254
270
*/
255
- LoginContext context = new LoginContext ("" , new Subject (), null ,
256
- new Configuration () {
257
- @ Override
258
- public AppConfigurationEntry [] getAppConfigurationEntry (String name ) {
259
- Map <String , String > options = new HashMap <>();
260
- options .put ("useKeyTab" , "false" );
261
- options .put ("storeKey" , "false" );
262
- options .put ("doNotPrompt" , "true" );
263
- options .put ("useTicketCache" , "true" );
264
- options .put ("renewTGT" , "true" );
265
- options .put ("refreshKrb5Config" , "true" );
266
- options .put ("isInitiator" , "true" );
267
- String ticketCache = System .getenv ("KRB5CCNAME" );
268
- if (ticketCache != null ) {
269
- options .put ("ticketCache" , ticketCache );
270
- }
271
- options .put ("debug" , "true" );
272
-
273
- return new AppConfigurationEntry []{
274
- new AppConfigurationEntry ("com.sun.security.auth.module.Krb5LoginModule" ,
275
- AppConfigurationEntry .LoginModuleControlFlag .REQUIRED ,
276
- options )};
277
- }
278
- });
271
+ LoginContext context ;
272
+
273
+ if (keyTab != null ) {
274
+ // To authenticate the HttpDoAsClient using principal and keyTab
275
+ Set <Principal > principals = new HashSet <>();
276
+ principals .add (new KerberosPrincipal (principal ));
277
+ Subject subject =
278
+ new Subject (false , principals , new HashSet <>(), new HashSet <>());
279
+
280
+ context = new LoginContext ("" , subject , null , new KerberosConfiguration (principal , keyTab ));
281
+ } else {
282
+ /*
283
+ * To authenticate the HttpDoAsClient, kinit should be invoked ahead. Here we try to
284
+ * get the Kerberos credential from the ticket cache.
285
+ */
286
+ context = new LoginContext ("" , new Subject (), null , new KerberosConfiguration ());
287
+ }
279
288
context .login ();
280
289
return context .getSubject ();
281
290
}
291
+
292
+ private static class KerberosConfiguration extends Configuration {
293
+ private String principal ;
294
+ private String keyTab ;
295
+
296
+ public KerberosConfiguration () {
297
+ // Empty constructor will have no principal or keyTab values
298
+ }
299
+
300
+ public KerberosConfiguration (String principal , String keyTab ) {
301
+ this .principal = principal ;
302
+ this .keyTab = keyTab ;
303
+ }
304
+
305
+ @ Override
306
+ public AppConfigurationEntry [] getAppConfigurationEntry (String name ) {
307
+ Map <String , String > options = new HashMap <>();
308
+ if (principal != null && keyTab != null ) {
309
+ options .put ("principal" , principal );
310
+ options .put ("keyTab" , keyTab );
311
+ options .put ("useKeyTab" , "true" );
312
+ options .put ("storeKey" , "true" );
313
+ } else {
314
+ options .put ("useKeyTab" , "false" );
315
+ options .put ("storeKey" , "false" );
316
+ }
317
+ options .put ("doNotPrompt" , "true" );
318
+ options .put ("useTicketCache" , "true" );
319
+ options .put ("renewTGT" , "true" );
320
+ options .put ("refreshKrb5Config" , "true" );
321
+ options .put ("isInitiator" , "true" );
322
+ String ticketCache = System .getenv ("KRB5CCNAME" );
323
+ if (ticketCache != null ) {
324
+ options .put ("ticketCache" , ticketCache );
325
+ }
326
+ options .put ("debug" , "true" );
327
+
328
+ return new AppConfigurationEntry [] {
329
+ new AppConfigurationEntry ("com.sun.security.auth.module.Krb5LoginModule" ,
330
+ AppConfigurationEntry .LoginModuleControlFlag .REQUIRED , options ) };
331
+ }
332
+ }
282
333
}
0 commit comments