@Test public void testUGIAuthMethodInRealUser() throws Exception { final UserGroupInformation ugi = UserGroupInformation.getCurrentUser(); UserGroupInformation proxyUgi = UserGroupInformation.createProxyUser("proxy", ugi); final AuthenticationMethod am = AuthenticationMethod.KERBEROS; ugi.setAuthenticationMethod(am); Assert.assertEquals(am, ugi.getAuthenticationMethod()); Assert.assertEquals(AuthenticationMethod.PROXY, proxyUgi.getAuthenticationMethod()); proxyUgi.doAs( new PrivilegedExceptionAction<Object>() { public Object run() throws IOException { Assert.assertEquals( AuthenticationMethod.PROXY, UserGroupInformation.getCurrentUser().getAuthenticationMethod()); Assert.assertEquals( am, UserGroupInformation.getCurrentUser().getRealUser().getAuthenticationMethod()); return null; } }); UserGroupInformation proxyUgi2 = new UserGroupInformation(proxyUgi.getSubject()); proxyUgi2.setAuthenticationMethod(AuthenticationMethod.PROXY); Assert.assertEquals(proxyUgi, proxyUgi2); // Equality should work if authMethod is null UserGroupInformation realugi = UserGroupInformation.getCurrentUser(); UserGroupInformation proxyUgi3 = UserGroupInformation.createProxyUser("proxyAnother", realugi); UserGroupInformation proxyUgi4 = new UserGroupInformation(proxyUgi3.getSubject()); Assert.assertEquals(proxyUgi3, proxyUgi4); }
/** * Log a user in from a keytab file. Loads a user identity from a keytab file and login them in. * This new user does not affect the currently logged-in user. * * @param user the principal name to load from the keytab * @param path the path to the keytab file * @throws IOException if the keytab file can't be read */ public static synchronized UserGroupInformation loginUserFromKeytabAndReturnUGI( String user, String path) throws IOException { if (!isSecurityEnabled()) return UserGroupInformation.getCurrentUser(); String oldKeytabFile = null; String oldKeytabPrincipal = null; long start = 0; try { oldKeytabFile = keytabFile; oldKeytabPrincipal = keytabPrincipal; keytabFile = path; keytabPrincipal = user; Subject subject = new Subject(); LoginContext login = new LoginContext(HadoopConfiguration.KEYTAB_KERBEROS_CONFIG_NAME, subject); start = System.currentTimeMillis(); login.login(); metrics.loginSuccess.inc(System.currentTimeMillis() - start); UserGroupInformation newLoginUser = new UserGroupInformation(subject); newLoginUser.setLogin(login); newLoginUser.setAuthenticationMethod(AuthenticationMethod.KERBEROS); return newLoginUser; } catch (LoginException le) { if (start > 0) { metrics.loginFailure.inc(System.currentTimeMillis() - start); } throw new IOException("Login failure for " + user + " from keytab " + path, le); } finally { if (oldKeytabFile != null) keytabFile = oldKeytabFile; if (oldKeytabPrincipal != null) keytabPrincipal = oldKeytabPrincipal; } }
/** * Log a user in from a keytab file. Loads a user identity from a keytab file and logs them in. * They become the currently logged-in user. * * @param user the principal name to load from the keytab * @param path the path to the keytab file * @throws IOException if the keytab file can't be read */ public static synchronized void loginUserFromKeytab(String user, String path) throws IOException { if (!isSecurityEnabled()) { return; } keytabFile = path; keytabPrincipal = user; Subject subject = new Subject(); LoginContext login; long start = 0; try { login = new LoginContext(HadoopConfiguration.KEYTAB_KERBEROS_CONFIG_NAME, subject); start = System.currentTimeMillis(); login.login(); metrics.loginSuccess.inc(System.currentTimeMillis() - start); loginUser = new UserGroupInformation(subject); loginUser.setLogin(login); loginUser.setAuthenticationMethod(AuthenticationMethod.KERBEROS); } catch (LoginException le) { if (start > 0) { metrics.loginFailure.inc(System.currentTimeMillis() - start); } throw new IOException("Login failure for " + user + " from keytab " + path, le); } LOG.info("Login successful for user " + keytabPrincipal + " using keytab file " + keytabFile); }
/** * Create a user from a login name. It is intended to be used for remote users in RPC, since it * won't have any credentials. * * @param user the full user principal name, must not be empty or null * @return the UserGroupInformation for the remote user. */ public static UserGroupInformation createRemoteUser(String user) { if (user == null || "".equals(user)) { throw new IllegalArgumentException("Null user"); } Subject subject = new Subject(); subject.getPrincipals().add(new User(user)); UserGroupInformation result = new UserGroupInformation(subject); result.setAuthenticationMethod(AuthenticationMethod.SIMPLE); return result; }
public static UserGroupInformation createConfigFileUser(String user, String password) { if (user == null || "".equals(user)) { throw new IllegalArgumentException("Null user"); } Subject subject = new Subject(); subject.getPrincipals().add(new User(user)); subject.getPrivateCredentials().add(new ConfigFileCredentials(password)); UserGroupInformation result = new UserGroupInformation(subject); result.setAuthenticationMethod(AuthenticationMethod.CONFIGFILE); return result; }
@Test public void testUGIAuthMethod() throws Exception { final UserGroupInformation ugi = UserGroupInformation.getCurrentUser(); final AuthenticationMethod am = AuthenticationMethod.KERBEROS; ugi.setAuthenticationMethod(am); Assert.assertEquals(am, ugi.getAuthenticationMethod()); ugi.doAs( new PrivilegedExceptionAction<Object>() { public Object run() throws IOException { Assert.assertEquals( am, UserGroupInformation.getCurrentUser().getAuthenticationMethod()); return null; } }); }
/** * Create a proxy user using username of the effective user and the ugi of the real user. * * @param user * @param realUser * @return proxyUser ugi */ public static UserGroupInformation createProxyUser(String user, UserGroupInformation realUser) { if (user == null || "".equals(user)) { throw new IllegalArgumentException("Null user"); } if (realUser == null) { throw new IllegalArgumentException("Null real user"); } Subject subject = new Subject(); Set<Principal> principals = subject.getPrincipals(); principals.add(new User(user)); principals.add(new RealUser(realUser)); UserGroupInformation result = new UserGroupInformation(subject); result.setAuthenticationMethod(AuthenticationMethod.PROXY); return result; }
/** * Get the currently logged in user. * * @return the logged in user * @throws IOException if login fails */ public static synchronized UserGroupInformation getLoginUser() throws IOException { if (loginUser == null) { try { Subject subject = new Subject(); LoginContext login; if (isSecurityEnabled()) { login = new LoginContext(HadoopConfiguration.USER_KERBEROS_CONFIG_NAME, subject); } else if (useConfiguredFileAuth) { login = new LoginContext(HadoopConfiguration.FILE_CONFIG_NAME, subject); } else { login = new LoginContext(HadoopConfiguration.SIMPLE_CONFIG_NAME, subject); } login.login(); loginUser = new UserGroupInformation(subject); loginUser.setLogin(login); // loginUser.setAuthenticationMethod(isSecurityEnabled() ? // AuthenticationMethod.KERBEROS : // AuthenticationMethod.SIMPLE); AuthenticationMethod authMethod = AuthenticationMethod.SIMPLE; if (isSecurityEnabled()) { authMethod = AuthenticationMethod.KERBEROS; } else if (useConfiguredFileAuth) { authMethod = AuthenticationMethod.CONFIGFILE; } else { authMethod = AuthenticationMethod.SIMPLE; } loginUser.setAuthenticationMethod(authMethod); loginUser = new UserGroupInformation(login.getSubject()); String fileLocation = System.getenv(HADOOP_TOKEN_FILE_LOCATION); if (fileLocation != null && isSecurityEnabled()) { // load the token storage file and put all of the tokens into the // user. Credentials cred = Credentials.readTokenStorageFiles(fileLocation, conf); for (Token<?> token : cred.getAllTokens()) { loginUser.addToken(token); } } loginUser.spawnAutoRenewalThreadForUserCreds(); } catch (LoginException le) { throw new IOException("failure to login", le); } } return loginUser; }
private static UserGroupInformation initUGI( final UserGroupInformation realUgi, final String doAsUserFromQuery, final HttpServletRequest request, final boolean isSecurityEnabled, final Configuration conf) throws AuthorizationException { final UserGroupInformation ugi; if (doAsUserFromQuery == null) { // non-proxy case ugi = realUgi; } else { // proxy case ugi = UserGroupInformation.createProxyUser(doAsUserFromQuery, realUgi); ugi.setAuthenticationMethod( isSecurityEnabled ? AuthenticationMethod.PROXY : AuthenticationMethod.SIMPLE); ProxyUsers.authorize(ugi, request.getRemoteAddr(), conf); } return ugi; }
@Test(timeout = 60000) public void testSecureProxyAuthParamsInUrl() throws IOException { Configuration conf = new Configuration(); // fake turning on security so api thinks it should use tokens SecurityUtil.setAuthenticationMethod(KERBEROS, conf); UserGroupInformation.setConfiguration(conf); UserGroupInformation ugi = UserGroupInformation.createRemoteUser("test-user"); ugi.setAuthenticationMethod(KERBEROS); ugi = UserGroupInformation.createProxyUser("test-proxy-user", ugi); UserGroupInformation.setLoginUser(ugi); WebHdfsFileSystem webhdfs = getWebHdfsFileSystem(ugi, conf); Path fsPath = new Path("/"); String tokenString = webhdfs.getDelegationToken().encodeToUrlString(); // send real+effective URL getTokenUrl = webhdfs.toUrl(GetOpParam.Op.GETDELEGATIONTOKEN, fsPath); checkQueryParams( new String[] { GetOpParam.Op.GETDELEGATIONTOKEN.toQueryString(), new UserParam(ugi.getRealUser().getShortUserName()).toString(), new DoAsParam(ugi.getShortUserName()).toString() }, getTokenUrl); // send real+effective URL renewTokenUrl = webhdfs.toUrl( PutOpParam.Op.RENEWDELEGATIONTOKEN, fsPath, new TokenArgumentParam(tokenString)); checkQueryParams( new String[] { PutOpParam.Op.RENEWDELEGATIONTOKEN.toQueryString(), new UserParam(ugi.getRealUser().getShortUserName()).toString(), new DoAsParam(ugi.getShortUserName()).toString(), new TokenArgumentParam(tokenString).toString(), }, renewTokenUrl); // send token URL cancelTokenUrl = webhdfs.toUrl( PutOpParam.Op.CANCELDELEGATIONTOKEN, fsPath, new TokenArgumentParam(tokenString)); checkQueryParams( new String[] { PutOpParam.Op.CANCELDELEGATIONTOKEN.toQueryString(), new UserParam(ugi.getRealUser().getShortUserName()).toString(), new DoAsParam(ugi.getShortUserName()).toString(), new TokenArgumentParam(tokenString).toString(), }, cancelTokenUrl); // send token URL fileStatusUrl = webhdfs.toUrl(GetOpParam.Op.GETFILESTATUS, fsPath); checkQueryParams( new String[] { GetOpParam.Op.GETFILESTATUS.toQueryString(), new DelegationParam(tokenString).toString() }, fileStatusUrl); // wipe out internal token to simulate auth always required webhdfs.setDelegationToken(null); // send real+effective cancelTokenUrl = webhdfs.toUrl( PutOpParam.Op.CANCELDELEGATIONTOKEN, fsPath, new TokenArgumentParam(tokenString)); checkQueryParams( new String[] { PutOpParam.Op.CANCELDELEGATIONTOKEN.toQueryString(), new UserParam(ugi.getRealUser().getShortUserName()).toString(), new DoAsParam(ugi.getShortUserName()).toString(), new TokenArgumentParam(tokenString).toString() }, cancelTokenUrl); // send real+effective fileStatusUrl = webhdfs.toUrl(GetOpParam.Op.GETFILESTATUS, fsPath); checkQueryParams( new String[] { GetOpParam.Op.GETFILESTATUS.toQueryString(), new UserParam(ugi.getRealUser().getShortUserName()).toString(), new DoAsParam(ugi.getShortUserName()).toString() }, fileStatusUrl); }
/** * Get {@link UserGroupInformation} and possibly the delegation token out of the request. * * @param context the Servlet context * @param request the http request * @param conf configuration * @param secureAuthMethod the AuthenticationMethod used in secure mode. * @param tryUgiParameter Should it try the ugi parameter? * @return a new user from the request * @throws AccessControlException if the request has no token */ public static UserGroupInformation getUGI( ServletContext context, HttpServletRequest request, Configuration conf, final AuthenticationMethod secureAuthMethod, final boolean tryUgiParameter) throws IOException { final UserGroupInformation ugi; final String usernameFromQuery = getUsernameFromQuery(request, tryUgiParameter); final String doAsUserFromQuery = request.getParameter(DoAsParam.NAME); if (UserGroupInformation.isSecurityEnabled()) { final String remoteUser = request.getRemoteUser(); String tokenString = request.getParameter(DELEGATION_PARAMETER_NAME); if (tokenString != null) { Token<DelegationTokenIdentifier> token = new Token<DelegationTokenIdentifier>(); token.decodeFromUrlString(tokenString); SecurityUtil.setTokenService(token, NameNode.getAddress(conf)); token.setKind(DelegationTokenIdentifier.HDFS_DELEGATION_KIND); ByteArrayInputStream buf = new ByteArrayInputStream(token.getIdentifier()); DataInputStream in = new DataInputStream(buf); DelegationTokenIdentifier id = new DelegationTokenIdentifier(); id.readFields(in); if (context != null) { NameNode nn = (NameNode) context.getAttribute("name.node"); if (nn != null) { // Verify the token. nn.getNamesystem() .getDelegationTokenSecretManager() .verifyToken(id, token.getPassword()); } } ugi = id.getUser(); if (ugi.getRealUser() == null) { // non-proxy case checkUsername(ugi.getShortUserName(), usernameFromQuery); checkUsername(null, doAsUserFromQuery); } else { // proxy case checkUsername(ugi.getRealUser().getShortUserName(), usernameFromQuery); checkUsername(ugi.getShortUserName(), doAsUserFromQuery); ProxyUsers.authorize(ugi, request.getRemoteAddr(), conf); } ugi.addToken(token); ugi.setAuthenticationMethod(AuthenticationMethod.TOKEN); } else { if (remoteUser == null) { throw new IOException("Security enabled but user not " + "authenticated by filter"); } final UserGroupInformation realUgi = UserGroupInformation.createRemoteUser(remoteUser); checkUsername(realUgi.getShortUserName(), usernameFromQuery); // This is not necessarily true, could have been auth'ed by user-facing // filter realUgi.setAuthenticationMethod(secureAuthMethod); ugi = initUGI(realUgi, doAsUserFromQuery, request, true, conf); } } else { // Security's not on, pull from url final UserGroupInformation realUgi = usernameFromQuery == null ? getDefaultWebUser(conf) // not specified in request : UserGroupInformation.createRemoteUser(usernameFromQuery); realUgi.setAuthenticationMethod(AuthenticationMethod.SIMPLE); ugi = initUGI(realUgi, doAsUserFromQuery, request, false, conf); } if (LOG.isDebugEnabled()) LOG.debug("getUGI is returning: " + ugi.getShortUserName()); return ugi; }