private void initWebHdfs(Configuration conf) throws IOException { if (WebHdfsFileSystem.isEnabled(conf, HttpServer2.LOG)) { // set user pattern based on configuration file UserParam.setUserPattern(conf.get( DFSConfigKeys.DFS_WEBHDFS_USER_PATTERN_KEY, DFSConfigKeys.DFS_WEBHDFS_USER_PATTERN_DEFAULT)); // add authentication filter for webhdfs final String className = conf.get( DFSConfigKeys.DFS_WEBHDFS_AUTHENTICATION_FILTER_KEY, DFSConfigKeys.DFS_WEBHDFS_AUTHENTICATION_FILTER_DEFAULT); final String name = className; final String pathSpec = WebHdfsFileSystem.PATH_PREFIX + "/*"; Map<String, String> params = getAuthFilterParams(conf); HttpServer2.defineFilter(httpServer.getWebAppContext(), name, className, params, new String[] { pathSpec }); HttpServer2.LOG.info("Added filter '" + name + "' (class=" + className + ")"); // add webhdfs packages httpServer.addJerseyResourcePackage(NamenodeWebHdfsMethods.class .getPackage().getName() + ";" + Param.class.getPackage().getName(), pathSpec); } }
@Test(timeout=60000) public void testSimpleAuthParamsInUrl() throws IOException { Configuration conf = new Configuration(); UserGroupInformation ugi = UserGroupInformation.createRemoteUser("test-user"); UserGroupInformation.setLoginUser(ugi); WebHdfsFileSystem webhdfs = getWebHdfsFileSystem(ugi, conf); Path fsPath = new Path("/"); // send user+token URL fileStatusUrl = webhdfs.toUrl(GetOpParam.Op.GETFILESTATUS, fsPath); checkQueryParams( new String[]{ GetOpParam.Op.GETFILESTATUS.toQueryString(), new UserParam(ugi.getShortUserName()).toString() }, fileStatusUrl); }
@Test(timeout=60000) public void testSimpleProxyAuthParamsInUrl() throws IOException { Configuration conf = new Configuration(); UserGroupInformation ugi = UserGroupInformation.createRemoteUser("test-user"); ugi = UserGroupInformation.createProxyUser("test-proxy-user", ugi); UserGroupInformation.setLoginUser(ugi); WebHdfsFileSystem webhdfs = getWebHdfsFileSystem(ugi, conf); Path fsPath = new Path("/"); // send real+effective URL 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); }
@Test(timeout=60000) public void testCheckAccessUrl() throws IOException { Configuration conf = new Configuration(); UserGroupInformation ugi = UserGroupInformation.createRemoteUser("test-user"); UserGroupInformation.setLoginUser(ugi); WebHdfsFileSystem webhdfs = getWebHdfsFileSystem(ugi, conf); Path fsPath = new Path("/p1"); URL checkAccessUrl = webhdfs.toUrl(GetOpParam.Op.CHECKACCESS, fsPath, new FsActionParam(FsAction.READ_WRITE)); checkQueryParams( new String[]{ GetOpParam.Op.CHECKACCESS.toQueryString(), new UserParam(ugi.getShortUserName()).toString(), FsActionParam.NAME + "=" + FsAction.READ_WRITE.SYMBOL }, checkAccessUrl); }
private void initWebHdfs(Configuration conf) throws IOException { // set user pattern based on configuration file UserParam.setUserPattern(conf.get( HdfsClientConfigKeys.DFS_WEBHDFS_USER_PATTERN_KEY, HdfsClientConfigKeys.DFS_WEBHDFS_USER_PATTERN_DEFAULT)); // add authentication filter for webhdfs final String className = conf.get( DFSConfigKeys.DFS_WEBHDFS_AUTHENTICATION_FILTER_KEY, DFSConfigKeys.DFS_WEBHDFS_AUTHENTICATION_FILTER_DEFAULT); final String name = className; final String pathSpec = WebHdfsFileSystem.PATH_PREFIX + "/*"; Map<String, String> params = getAuthFilterParams(conf); HttpServer2.defineFilter(httpServer.getWebAppContext(), name, className, params, new String[] { pathSpec }); HttpServer2.LOG.info("Added filter '" + name + "' (class=" + className + ")"); // add webhdfs packages httpServer.addJerseyResourcePackage(NamenodeWebHdfsMethods.class .getPackage().getName() + ";" + Param.class.getPackage().getName(), pathSpec); }
@Test(timeout = 15000) public void testNamenodeJspHelperRedirectToRandomDataNode() throws IOException, InterruptedException { final String urlPart = "browseDirectory.jsp?namenodeInfoPort="; ServletContext context = mock(ServletContext.class); HttpServletRequest request = mock(HttpServletRequest.class); HttpServletResponse resp = mock(HttpServletResponse.class); when(request.getScheme()).thenReturn("http"); when(request.getParameter(UserParam.NAME)).thenReturn("localuser"); when(context.getAttribute(NAMENODE_ATTRIBUTE_KEY)).thenReturn( cluster.getNameNode()); when(context.getAttribute(JspHelper.CURRENT_CONF)).thenReturn(conf); ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); doAnswer(new Answer<String>() { @Override public String answer(InvocationOnMock invocation) throws Throwable { return null; } }).when(resp).sendRedirect(captor.capture()); NamenodeJspHelper.redirectToRandomDataNode(context, request, resp); assertTrue(captor.getValue().contains(urlPart)); }
Param<?,?>[] getAuthParameters(final HttpOpParam.Op op) throws IOException { List<Param<?,?>> authParams = Lists.newArrayList(); // Skip adding delegation token for token operations because these // operations require authentication. Token<?> token = null; if (UserGroupInformation.isSecurityEnabled() && !op.getRequireAuth()) { token = getDelegationToken(); } if (token != null) { authParams.add(new DelegationParam(token.encodeToUrlString())); } else { UserGroupInformation userUgi = ugi; UserGroupInformation realUgi = userUgi.getRealUser(); if (realUgi != null) { // proxy user authParams.add(new DoAsParam(userUgi.getShortUserName())); userUgi = realUgi; } authParams.add(new UserParam(userUgi.getShortUserName())); } return authParams.toArray(new Param<?,?>[0]); }
/** Handle HTTP POST request for the root. */ @POST @Path("/") @Consumes({"*/*"}) @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON}) public Response postRoot( @Context final UserGroupInformation ugi, @QueryParam(DelegationParam.NAME) @DefaultValue(DelegationParam.DEFAULT) final DelegationParam delegation, @QueryParam(UserParam.NAME) @DefaultValue(UserParam.DEFAULT) final UserParam username, @QueryParam(DoAsParam.NAME) @DefaultValue(DoAsParam.DEFAULT) final DoAsParam doAsUser, @QueryParam(PostOpParam.NAME) @DefaultValue(PostOpParam.DEFAULT) final PostOpParam op, @QueryParam(ConcatSourcesParam.NAME) @DefaultValue(ConcatSourcesParam.DEFAULT) final ConcatSourcesParam concatSrcs, @QueryParam(BufferSizeParam.NAME) @DefaultValue(BufferSizeParam.DEFAULT) final BufferSizeParam bufferSize ) throws IOException, InterruptedException { return post(ugi, delegation, username, doAsUser, ROOT, op, concatSrcs, bufferSize); }
/** Handle HTTP GET request for the root. */ @GET @Path("/") @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON}) public Response getRoot( @Context final UserGroupInformation ugi, @QueryParam(DelegationParam.NAME) @DefaultValue(DelegationParam.DEFAULT) final DelegationParam delegation, @QueryParam(UserParam.NAME) @DefaultValue(UserParam.DEFAULT) final UserParam username, @QueryParam(DoAsParam.NAME) @DefaultValue(DoAsParam.DEFAULT) final DoAsParam doAsUser, @QueryParam(GetOpParam.NAME) @DefaultValue(GetOpParam.DEFAULT) final GetOpParam op, @QueryParam(OffsetParam.NAME) @DefaultValue(OffsetParam.DEFAULT) final OffsetParam offset, @QueryParam(LengthParam.NAME) @DefaultValue(LengthParam.DEFAULT) final LengthParam length, @QueryParam(RenewerParam.NAME) @DefaultValue(RenewerParam.DEFAULT) final RenewerParam renewer, @QueryParam(BufferSizeParam.NAME) @DefaultValue(BufferSizeParam.DEFAULT) final BufferSizeParam bufferSize ) throws IOException, InterruptedException { return get(ugi, delegation, username, doAsUser, ROOT, op, offset, length, renewer, bufferSize); }
/** Handle HTTP DELETE request for the root. */ @DELETE @Path("/") @Produces(MediaType.APPLICATION_JSON) public Response deleteRoot( @Context final UserGroupInformation ugi, @QueryParam(DelegationParam.NAME) @DefaultValue(DelegationParam.DEFAULT) final DelegationParam delegation, @QueryParam(UserParam.NAME) @DefaultValue(UserParam.DEFAULT) final UserParam username, @QueryParam(DoAsParam.NAME) @DefaultValue(DoAsParam.DEFAULT) final DoAsParam doAsUser, @QueryParam(DeleteOpParam.NAME) @DefaultValue(DeleteOpParam.DEFAULT) final DeleteOpParam op, @QueryParam(RecursiveParam.NAME) @DefaultValue(RecursiveParam.DEFAULT) final RecursiveParam recursive ) throws IOException, InterruptedException { return delete(ugi, delegation, username, doAsUser, ROOT, op, recursive); }
private Response delete( final UserGroupInformation ugi, final DelegationParam delegation, final UserParam username, final DoAsParam doAsUser, final String fullpath, final DeleteOpParam op, final RecursiveParam recursive ) throws IOException { final NameNode namenode = (NameNode)context.getAttribute("name.node"); switch(op.getValue()) { case DELETE: { final boolean b = namenode.getRpcServer().delete(fullpath, recursive.getValue()); final String js = JsonUtil.toJsonString("boolean", b); return Response.ok(js).type(MediaType.APPLICATION_JSON).build(); } default: throw new UnsupportedOperationException(op + " is not supported"); } }
private Response post(final UserGroupInformation ugi, final DelegationParam delegation, final UserParam username, final DoAsParam doAsUser, final String fullpath, final PostOpParam op, final ConcatSourcesParam concatSrcs, final BufferSizeParam bufferSize) throws IOException, URISyntaxException { final NameNode namenode = (NameNode) context.getAttribute("name.node"); switch (op.getValue()) { case APPEND: { final URI uri = redirectURI(namenode, ugi, delegation, username, doAsUser, fullpath, op.getValue(), -1L, -1L, bufferSize); return Response.temporaryRedirect(uri) .type(MediaType.APPLICATION_OCTET_STREAM).build(); } case CONCAT: { namenode.getRpcServer().concat(fullpath, concatSrcs.getAbsolutePaths()); return Response.ok().build(); } default: throw new UnsupportedOperationException(op + " is not supported"); } }
/** * Handle HTTP DELETE request for the root. */ @DELETE @Path("/") @Produces(MediaType.APPLICATION_JSON) public Response deleteRoot( @Context final UserGroupInformation ugi, @QueryParam(DelegationParam.NAME) @DefaultValue(DelegationParam.DEFAULT) final DelegationParam delegation, @QueryParam(UserParam.NAME) @DefaultValue(UserParam.DEFAULT) final UserParam username, @QueryParam(DoAsParam.NAME) @DefaultValue(DoAsParam.DEFAULT) final DoAsParam doAsUser, @QueryParam(DeleteOpParam.NAME) @DefaultValue(DeleteOpParam.DEFAULT) final DeleteOpParam op, @QueryParam(RecursiveParam.NAME) @DefaultValue(RecursiveParam.DEFAULT) final RecursiveParam recursive) throws IOException, InterruptedException { return delete(ugi, delegation, username, doAsUser, ROOT, op, recursive); }
private Response delete(final UserGroupInformation ugi, final DelegationParam delegation, final UserParam username, final DoAsParam doAsUser, final String fullpath, final DeleteOpParam op, final RecursiveParam recursive) throws IOException { final NameNode namenode = (NameNode) context.getAttribute("name.node"); switch (op.getValue()) { case DELETE: { final boolean b = namenode.getRpcServer().delete(fullpath, recursive.getValue()); final String js = JsonUtil.toJsonString("boolean", b); return Response.ok(js).type(MediaType.APPLICATION_JSON).build(); } default: throw new UnsupportedOperationException(op + " is not supported"); } }
@Test(timeout = 4000) public void testSimpleAuthParamsInUrl() throws IOException { Configuration conf = new Configuration(); UserGroupInformation ugi = UserGroupInformation.createRemoteUser("test-user"); UserGroupInformation.setLoginUser(ugi); WebHdfsFileSystem webhdfs = getWebHdfsFileSystem(ugi, conf); Path fsPath = new Path("/"); // send user+token URL fileStatusUrl = webhdfs.toUrl(GetOpParam.Op.GETFILESTATUS, fsPath); checkQueryParams(new String[]{GetOpParam.Op.GETFILESTATUS.toQueryString(), new UserParam(ugi.getShortUserName()).toString()}, fileStatusUrl); }
@Test(timeout = 4000) public void testSimpleProxyAuthParamsInUrl() throws IOException { Configuration conf = new Configuration(); UserGroupInformation ugi = UserGroupInformation.createRemoteUser("test-user"); ugi = UserGroupInformation.createProxyUser("test-proxy-user", ugi); UserGroupInformation.setLoginUser(ugi); WebHdfsFileSystem webhdfs = getWebHdfsFileSystem(ugi, conf); Path fsPath = new Path("/"); // send real+effective URL 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); }
URL toUrl(final HttpOpParam.Op op, final Path fspath, final Param<?,?>... parameters) throws IOException { //initialize URI path and query final String path = PATH_PREFIX + (fspath == null? "/": makeQualified(fspath).toUri().getPath()); final String query = op.toQueryString() + '&' + new UserParam(ugi) + Param.toSortedString("&", parameters); final URL url; if (op.equals(PutOpParam.Op.RENEWDELEGATIONTOKEN) || op.equals(GetOpParam.Op.GETDELEGATIONTOKEN)) { // Skip adding delegation token for getting or renewing delegation token, // because these operations require kerberos authentication. url = getNamenodeURL(path, query); } else { url = getNamenodeURL(path, addDt2Query(query)); } if (LOG.isTraceEnabled()) { LOG.trace("url=" + url); } return url; }
/** Handle HTTP POST request for the root. */ @POST @Path("/") @Consumes({"*/*"}) @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON}) public Response postRoot( @Context final UserGroupInformation ugi, @QueryParam(DelegationParam.NAME) @DefaultValue(DelegationParam.DEFAULT) final DelegationParam delegation, @QueryParam(UserParam.NAME) @DefaultValue(UserParam.DEFAULT) final UserParam username, @QueryParam(DoAsParam.NAME) @DefaultValue(DoAsParam.DEFAULT) final DoAsParam doAsUser, @QueryParam(PostOpParam.NAME) @DefaultValue(PostOpParam.DEFAULT) final PostOpParam op, @QueryParam(BufferSizeParam.NAME) @DefaultValue(BufferSizeParam.DEFAULT) final BufferSizeParam bufferSize ) throws IOException, InterruptedException { return post(ugi, delegation, username, doAsUser, ROOT, op, bufferSize); }