john lilley created HADOOP-12333:
------------------------------------
Summary: UserGroupInformation method to log in and relogin with
password
Key: HADOOP-12333
URL: https://issues.apache.org/jira/browse/HADOOP-12333
Project: Hadoop Common
Issue Type: Improvement
Components: security
Affects Versions: 2.6.0
Environment: all
Reporter: john lilley
UserGroupInformation lacks a simple method to login using a password, and also
makes an important method private. While many people seem to believe that
kinit should be used for passwords, it is unworkable in many cases (such as
when software is running as a service).
Currently to workaround we must do all of this:
// create a dynamic configuration for the LoginContext
Map<String,String> krbOptions = new HashMap<String,String>();
krbOptions.put("doNotPrompt", "false");
krbOptions.put("useTicketCache", "false");
krbOptions.put("useKeyTab", "false");
krbOptions.put("renewTGT", "false");
AppConfigurationEntry ace = new AppConfigurationEntry(
KerberosUtil.getKrb5LoginModuleName(), LoginModuleControlFlag.REQUIRED,
krbOptions);
DynamicConfiguration dynConf = new DynamicConfiguration(
new AppConfigurationEntry[] {ace});
// create LoginContext with login callback handler
LoginContext loginContext =
newLoginContext(USER_PASSWORD_LOGIN_KERBEROS_CONFIG_NAME,
null, new LoginHandler(userPrincipal, password), dynConf);
loginContext.login();
// get Subject and Principal for logged in user
Subject loginSubject = loginContext.getSubject();
Set<Principal> loginPrincipals = loginSubject.getPrincipals();
if (loginPrincipals.isEmpty()) {
throw new LoginException("No login principals in loginSubject: " +
loginSubject);
}
String username = loginPrincipals.iterator().next().getName();
Principal ugiUser = newUser(username, AuthenticationMethod.KERBEROS,
loginContext);
// update Hadoop security details
loginSubject.getPrincipals().add(ugiUser);
UserGroupInformation loginUser = newUserGroupInformation(loginSubject);
UserGroupInformation.setLoginUser(loginUser);
setUGILogin(loginUser, loginContext); // do loginUser.setLogin(loginContext)
loginUser.setAuthenticationMethod(AuthenticationMethod.KERBEROS);
Note the method setUGILogin() uses reflection to overcome private method that
we need:
private static void setUGILogin(UserGroupInformation loginUser, LoginContext
loginContext)
throws SecurityException, NoSuchMethodException,
IllegalArgumentException,
IllegalAccessException, InvocationTargetException
{
Class<UserGroupInformation> cls = UserGroupInformation.class;
Method mtd = cls.getDeclaredMethod("setLogin", LoginContext.class);
mtd.setAccessible(true);
mtd.invoke(loginUser, loginContext);
}
Finally there is no method reloginFromPassword(). While we can use reflection
to access the private methods needed for this, it should simply be supported.
PS: I really hope I've just missed something obvious and you can just call me
an idiot ;-)
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)