/** * Cancel a Delegation Token. * * @param nnAddr the NameNode's address * @param tok the token to cancel * @throws IOException */ public static void cancelDelegationToken(String nnAddr, Token<DelegationTokenIdentifier> tok) throws IOException { StringBuilder buf = new StringBuilder(); buf.append(nnAddr); buf.append(CancelDelegationTokenServlet.PATH_SPEC); buf.append("?"); buf.append(CancelDelegationTokenServlet.TOKEN); buf.append("="); buf.append(tok.encodeToUrlString()); BufferedReader in = null; HttpURLConnection connection = null; try { URL url = new URL(buf.toString()); SecurityUtil.fetchServiceTicket(url); connection = (HttpURLConnection) url.openConnection(); if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { throw new IOException("Error cancelling token: " + connection.getResponseMessage()); } } catch (IOException ie) { LOG.info("error in cancel over HTTP", ie); IOException e = getExceptionFromResponse(connection); IOUtils.cleanup(LOG, in); if (e != null) { LOG.info("rethrowing exception from HTTP request: " + e.getLocalizedMessage()); throw e; } throw ie; } }
private static Map<String, Object> toJsonMap(final Token<? extends TokenIdentifier> token) throws IOException { if (token == null) { return null; } final Map<String, Object> m = new TreeMap<String, Object>(); m.put("urlString", token.encodeToUrlString()); return m; }
@Test public void testGetUgi() throws IOException { conf.set(DFSConfigKeys.FS_DEFAULT_NAME_KEY, "hdfs://localhost:4321/"); HttpServletRequest request = mock(HttpServletRequest.class); ServletContext context = mock(ServletContext.class); String user = "******"; Text userText = new Text(user); DelegationTokenIdentifier dtId = new DelegationTokenIdentifier(userText, userText, null); Token<DelegationTokenIdentifier> token = new Token<DelegationTokenIdentifier>(dtId, new DummySecretManager(0, 0, 0, 0)); String tokenString = token.encodeToUrlString(); when(request.getParameter(JspHelper.DELEGATION_PARAMETER_NAME)).thenReturn(tokenString); when(request.getRemoteUser()).thenReturn(user); // Test attribute in the url to be used as service in the token. when(request.getParameter(JspHelper.NAMENODE_ADDRESS)).thenReturn("1.1.1.1:1111"); conf.set(DFSConfigKeys.HADOOP_SECURITY_AUTHENTICATION, "kerberos"); UserGroupInformation.setConfiguration(conf); verifyServiceInToken(context, request, "1.1.1.1:1111"); // Test attribute name.node.address // Set the nnaddr url parameter to null. when(request.getParameter(JspHelper.NAMENODE_ADDRESS)).thenReturn(null); InetSocketAddress addr = new InetSocketAddress("localhost", 2222); when(context.getAttribute(NameNodeHttpServer.NAMENODE_ADDRESS_ATTRIBUTE_KEY)).thenReturn(addr); verifyServiceInToken(context, request, addr.getAddress().getHostAddress() + ":2222"); // Test service already set in the token token.setService(new Text("3.3.3.3:3333")); tokenString = token.encodeToUrlString(); // Set the name.node.address attribute in Servlet context to null when(context.getAttribute(NameNodeHttpServer.NAMENODE_ADDRESS_ATTRIBUTE_KEY)).thenReturn(null); when(request.getParameter(JspHelper.DELEGATION_PARAMETER_NAME)).thenReturn(tokenString); verifyServiceInToken(context, request, "3.3.3.3:3333"); }
static String getDelegationToken( final NamenodeProtocols nn, HttpServletRequest request, Configuration conf, final UserGroupInformation ugi) throws IOException, InterruptedException { Token<DelegationTokenIdentifier> token = ugi.doAs( new PrivilegedExceptionAction<Token<DelegationTokenIdentifier>>() { @Override public Token<DelegationTokenIdentifier> run() throws IOException { return nn.getDelegationToken(new Text(ugi.getUserName())); } }); return token == null ? null : token.encodeToUrlString(); }
private URI redirectURI( final NameNode namenode, final UserGroupInformation ugi, final DelegationParam delegation, final UserParam username, final DoAsParam doAsUser, final String path, final HttpOpParam.Op op, final long openOffset, final long blocksize, final Param<?, ?>... parameters) throws URISyntaxException, IOException { final Configuration conf = (Configuration) context.getAttribute(JspHelper.CURRENT_CONF); final DatanodeInfo dn = chooseDatanode(namenode, path, op, openOffset, blocksize, conf); final String delegationQuery; if (!UserGroupInformation.isSecurityEnabled()) { // security disabled delegationQuery = Param.toSortedString("&", doAsUser, username); } else if (delegation.getValue() != null) { // client has provided a token delegationQuery = "&" + delegation; } else { // generate a token final Token<? extends TokenIdentifier> t = generateDelegationToken(namenode, ugi, request.getUserPrincipal().getName()); delegationQuery = "&" + new DelegationParam(t.encodeToUrlString()); } final String query = op.toQueryString() + delegationQuery + "&" + new NamenodeRpcAddressParam(namenode) + Param.toSortedString("&", parameters); final String uripath = WebHdfsFileSystem.PATH_PREFIX + path; final URI uri = new URI("http", null, dn.getHostName(), dn.getInfoPort(), uripath, query, null); if (LOG.isTraceEnabled()) { LOG.trace("redirectURI=" + uri); } return uri; }
@Test public void testGetUgiFromToken() throws IOException { conf.set(DFSConfigKeys.FS_DEFAULT_NAME_KEY, "hdfs://localhost:4321/"); ServletContext context = mock(ServletContext.class); String realUser = "******"; String user = "******"; conf.set(DFSConfigKeys.HADOOP_SECURITY_AUTHENTICATION, "kerberos"); UserGroupInformation.setConfiguration(conf); UserGroupInformation ugi; HttpServletRequest request; Text ownerText = new Text(user); DelegationTokenIdentifier dtId = new DelegationTokenIdentifier(ownerText, ownerText, new Text(realUser)); Token<DelegationTokenIdentifier> token = new Token<DelegationTokenIdentifier>(dtId, new DummySecretManager(0, 0, 0, 0)); String tokenString = token.encodeToUrlString(); // token with no auth-ed user request = getMockRequest(null, null, null); when(request.getParameter(JspHelper.DELEGATION_PARAMETER_NAME)).thenReturn(tokenString); ugi = JspHelper.getUGI(context, request, conf); Assert.assertNotNull(ugi.getRealUser()); Assert.assertEquals(ugi.getRealUser().getShortUserName(), realUser); Assert.assertEquals(ugi.getShortUserName(), user); checkUgiFromToken(ugi); // token with auth-ed user request = getMockRequest(realUser, null, null); when(request.getParameter(JspHelper.DELEGATION_PARAMETER_NAME)).thenReturn(tokenString); ugi = JspHelper.getUGI(context, request, conf); Assert.assertNotNull(ugi.getRealUser()); Assert.assertEquals(ugi.getRealUser().getShortUserName(), realUser); Assert.assertEquals(ugi.getShortUserName(), user); checkUgiFromToken(ugi); // completely different user, token trumps auth request = getMockRequest("rogue", null, null); when(request.getParameter(JspHelper.DELEGATION_PARAMETER_NAME)).thenReturn(tokenString); ugi = JspHelper.getUGI(context, request, conf); Assert.assertNotNull(ugi.getRealUser()); Assert.assertEquals(ugi.getRealUser().getShortUserName(), realUser); Assert.assertEquals(ugi.getShortUserName(), user); checkUgiFromToken(ugi); // expected case request = getMockRequest(null, user, null); when(request.getParameter(JspHelper.DELEGATION_PARAMETER_NAME)).thenReturn(tokenString); ugi = JspHelper.getUGI(context, request, conf); Assert.assertNotNull(ugi.getRealUser()); Assert.assertEquals(ugi.getRealUser().getShortUserName(), realUser); Assert.assertEquals(ugi.getShortUserName(), user); checkUgiFromToken(ugi); // can't proxy with a token! request = getMockRequest(null, null, "rogue"); when(request.getParameter(JspHelper.DELEGATION_PARAMETER_NAME)).thenReturn(tokenString); try { JspHelper.getUGI(context, request, conf); Assert.fail("bad request allowed"); } catch (IOException ioe) { Assert.assertEquals( "Usernames not matched: name=rogue != expected=" + user, ioe.getMessage()); } // can't proxy with a token! request = getMockRequest(null, user, "rogue"); when(request.getParameter(JspHelper.DELEGATION_PARAMETER_NAME)).thenReturn(tokenString); try { JspHelper.getUGI(context, request, conf); Assert.fail("bad request allowed"); } catch (IOException ioe) { Assert.assertEquals( "Usernames not matched: name=rogue != expected=" + user, ioe.getMessage()); } }