[ https://issues.apache.org/jira/browse/HADOOP-12333?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14703200#comment-14703200 ]
john lilley commented on HADOOP-12333: -------------------------------------- Perhaps I just don't understand what you mean by "from-client refresh of tickets". We have is a service running on a non-Hadoop node, under either Windows or Linux. That presents as a GUI to a client where the user logs in. The client can be running anywhere and has no direct access to Hadoop at all (by design -- it may be across dialup VPN and firewalled off from the cluster). So the client ships the login/password to our service, which spawns a new process under the user's OS credentials, and that process does the UGI authentication to get a ticket. But now the clock is ticking, and we must re-authorize. With keytab we simply call reloginFromKeytab(). With password there doesn't seem to be any direct support. > 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)