| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.hadoop.fs.http.server; |
| |
| import junit.framework.Assert; |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hadoop.fs.http.client.HttpFSFileSystem; |
| import org.apache.hadoop.fs.http.client.HttpFSKerberosAuthenticator; |
| import org.apache.hadoop.fs.http.client.HttpFSKerberosAuthenticator.DelegationTokenOperation; |
| import org.apache.hadoop.lib.service.DelegationTokenIdentifier; |
| import org.apache.hadoop.lib.service.DelegationTokenManager; |
| import org.apache.hadoop.lib.service.DelegationTokenManagerException; |
| import org.apache.hadoop.security.UserGroupInformation; |
| import org.apache.hadoop.security.authentication.client.AuthenticationException; |
| import org.apache.hadoop.security.authentication.server.AuthenticationHandler; |
| import org.apache.hadoop.security.authentication.server.AuthenticationToken; |
| import org.apache.hadoop.security.token.Token; |
| import org.apache.hadoop.test.HFSTestCase; |
| import org.apache.hadoop.test.TestDir; |
| import org.apache.hadoop.test.TestDirHelper; |
| import org.json.simple.JSONObject; |
| import org.json.simple.parser.JSONParser; |
| import org.junit.Test; |
| import org.mockito.Mockito; |
| |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| import javax.ws.rs.core.MediaType; |
| import java.io.PrintWriter; |
| import java.io.StringWriter; |
| import java.net.InetAddress; |
| import java.net.InetSocketAddress; |
| |
| public class TestHttpFSKerberosAuthenticationHandler extends HFSTestCase { |
| |
| @Test |
| @TestDir |
| public void testManagementOperations() throws Exception { |
| String dir = TestDirHelper.getTestDir().getAbsolutePath(); |
| |
| Configuration httpfsConf = new Configuration(false); |
| HttpFSServerWebApp server = |
| new HttpFSServerWebApp(dir, dir, dir, dir, httpfsConf); |
| server.setAuthority(new InetSocketAddress(InetAddress.getLocalHost(), |
| 14000)); |
| AuthenticationHandler handler = |
| new HttpFSKerberosAuthenticationHandlerForTesting(); |
| try { |
| server.init(); |
| handler.init(null); |
| |
| testNonManagementOperation(handler); |
| testManagementOperationErrors(handler); |
| testGetToken(handler, null); |
| testGetToken(handler, "foo"); |
| testCancelToken(handler); |
| testRenewToken(handler); |
| |
| } finally { |
| if (handler != null) { |
| handler.destroy(); |
| } |
| server.destroy(); |
| } |
| } |
| |
| private void testNonManagementOperation(AuthenticationHandler handler) |
| throws Exception { |
| HttpServletRequest request = Mockito.mock(HttpServletRequest.class); |
| Mockito.when(request.getParameter(HttpFSFileSystem.OP_PARAM)). |
| thenReturn(null); |
| Assert.assertTrue(handler.managementOperation(null, request, null)); |
| Mockito.when(request.getParameter(HttpFSFileSystem.OP_PARAM)). |
| thenReturn(HttpFSFileSystem.Operation.CREATE.toString()); |
| Assert.assertTrue(handler.managementOperation(null, request, null)); |
| } |
| |
| private void testManagementOperationErrors(AuthenticationHandler handler) |
| throws Exception { |
| HttpServletRequest request = Mockito.mock(HttpServletRequest.class); |
| HttpServletResponse response = Mockito.mock(HttpServletResponse.class); |
| Mockito.when(request.getParameter(HttpFSFileSystem.OP_PARAM)). |
| thenReturn(DelegationTokenOperation.GETDELEGATIONTOKEN.toString()); |
| Mockito.when(request.getMethod()).thenReturn("FOO"); |
| Assert.assertFalse(handler.managementOperation(null, request, response)); |
| Mockito.verify(response).sendError( |
| Mockito.eq(HttpServletResponse.SC_BAD_REQUEST), |
| Mockito.startsWith("Wrong HTTP method")); |
| |
| Mockito.reset(response); |
| Mockito.when(request.getMethod()). |
| thenReturn(DelegationTokenOperation.GETDELEGATIONTOKEN.getHttpMethod()); |
| Assert.assertFalse(handler.managementOperation(null, request, response)); |
| Mockito.verify(response).sendError( |
| Mockito.eq(HttpServletResponse.SC_UNAUTHORIZED), |
| Mockito.contains("requires SPNEGO")); |
| } |
| |
| private void testGetToken(AuthenticationHandler handler, String renewer) |
| throws Exception { |
| DelegationTokenOperation op = DelegationTokenOperation.GETDELEGATIONTOKEN; |
| HttpServletRequest request = Mockito.mock(HttpServletRequest.class); |
| HttpServletResponse response = Mockito.mock(HttpServletResponse.class); |
| Mockito.when(request.getParameter(HttpFSFileSystem.OP_PARAM)). |
| thenReturn(op.toString()); |
| Mockito.when(request.getMethod()). |
| thenReturn(op.getHttpMethod()); |
| |
| AuthenticationToken token = Mockito.mock(AuthenticationToken.class); |
| Mockito.when(token.getUserName()).thenReturn("user"); |
| Assert.assertFalse(handler.managementOperation(null, request, response)); |
| Mockito.when(request.getParameter(HttpFSKerberosAuthenticator.RENEWER_PARAM)). |
| thenReturn(renewer); |
| |
| Mockito.reset(response); |
| StringWriter writer = new StringWriter(); |
| PrintWriter pwriter = new PrintWriter(writer); |
| Mockito.when(response.getWriter()).thenReturn(pwriter); |
| Assert.assertFalse(handler.managementOperation(token, request, response)); |
| if (renewer == null) { |
| Mockito.verify(token).getUserName(); |
| } else { |
| Mockito.verify(token, Mockito.never()).getUserName(); |
| } |
| Mockito.verify(response).setStatus(HttpServletResponse.SC_OK); |
| Mockito.verify(response).setContentType(MediaType.APPLICATION_JSON); |
| pwriter.close(); |
| String responseOutput = writer.toString(); |
| String tokenLabel = HttpFSKerberosAuthenticator.DELEGATION_TOKEN_JSON; |
| Assert.assertTrue(responseOutput.contains(tokenLabel)); |
| Assert.assertTrue(responseOutput.contains( |
| HttpFSKerberosAuthenticator.DELEGATION_TOKEN_URL_STRING_JSON)); |
| JSONObject json = (JSONObject) new JSONParser().parse(responseOutput); |
| json = (JSONObject) json.get(tokenLabel); |
| String tokenStr; |
| tokenStr = (String) |
| json.get(HttpFSKerberosAuthenticator.DELEGATION_TOKEN_URL_STRING_JSON); |
| Token<DelegationTokenIdentifier> dt = new Token<DelegationTokenIdentifier>(); |
| dt.decodeFromUrlString(tokenStr); |
| HttpFSServerWebApp.get().get(DelegationTokenManager.class).verifyToken(dt); |
| } |
| |
| private void testCancelToken(AuthenticationHandler handler) |
| throws Exception { |
| DelegationTokenOperation op = |
| DelegationTokenOperation.CANCELDELEGATIONTOKEN; |
| HttpServletRequest request = Mockito.mock(HttpServletRequest.class); |
| HttpServletResponse response = Mockito.mock(HttpServletResponse.class); |
| Mockito.when(request.getParameter(HttpFSFileSystem.OP_PARAM)). |
| thenReturn(op.toString()); |
| Mockito.when(request.getMethod()). |
| thenReturn(op.getHttpMethod()); |
| |
| Assert.assertFalse(handler.managementOperation(null, request, response)); |
| Mockito.verify(response).sendError( |
| Mockito.eq(HttpServletResponse.SC_BAD_REQUEST), |
| Mockito.contains("requires the parameter [token]")); |
| |
| Mockito.reset(response); |
| Token<DelegationTokenIdentifier> token = |
| HttpFSServerWebApp.get().get(DelegationTokenManager.class).createToken( |
| UserGroupInformation.getCurrentUser(), "foo"); |
| Mockito.when(request.getParameter(HttpFSKerberosAuthenticator.TOKEN_PARAM)). |
| thenReturn(token.encodeToUrlString()); |
| Assert.assertFalse(handler.managementOperation(null, request, response)); |
| Mockito.verify(response).setStatus(HttpServletResponse.SC_OK); |
| try { |
| HttpFSServerWebApp.get().get(DelegationTokenManager.class).verifyToken(token); |
| Assert.fail(); |
| } |
| catch (DelegationTokenManagerException ex) { |
| Assert.assertTrue(ex.toString().contains("DT01")); |
| } |
| } |
| |
| private void testRenewToken(AuthenticationHandler handler) |
| throws Exception { |
| DelegationTokenOperation op = |
| DelegationTokenOperation.RENEWDELEGATIONTOKEN; |
| HttpServletRequest request = Mockito.mock(HttpServletRequest.class); |
| HttpServletResponse response = Mockito.mock(HttpServletResponse.class); |
| Mockito.when(request.getParameter(HttpFSFileSystem.OP_PARAM)). |
| thenReturn(op.toString()); |
| Mockito.when(request.getMethod()). |
| thenReturn(op.getHttpMethod()); |
| |
| Assert.assertFalse(handler.managementOperation(null, request, response)); |
| Mockito.verify(response).sendError( |
| Mockito.eq(HttpServletResponse.SC_UNAUTHORIZED), |
| Mockito.contains("equires SPNEGO authentication established")); |
| |
| Mockito.reset(response); |
| AuthenticationToken token = Mockito.mock(AuthenticationToken.class); |
| Mockito.when(token.getUserName()).thenReturn("user"); |
| Assert.assertFalse(handler.managementOperation(token, request, response)); |
| Mockito.verify(response).sendError( |
| Mockito.eq(HttpServletResponse.SC_BAD_REQUEST), |
| Mockito.contains("requires the parameter [token]")); |
| |
| Mockito.reset(response); |
| StringWriter writer = new StringWriter(); |
| PrintWriter pwriter = new PrintWriter(writer); |
| Mockito.when(response.getWriter()).thenReturn(pwriter); |
| Token<DelegationTokenIdentifier> dToken = |
| HttpFSServerWebApp.get().get(DelegationTokenManager.class).createToken( |
| UserGroupInformation.getCurrentUser(), "user"); |
| Mockito.when(request.getParameter(HttpFSKerberosAuthenticator.TOKEN_PARAM)). |
| thenReturn(dToken.encodeToUrlString()); |
| Assert.assertFalse(handler.managementOperation(token, request, response)); |
| Mockito.verify(response).setStatus(HttpServletResponse.SC_OK); |
| pwriter.close(); |
| Assert.assertTrue(writer.toString().contains("long")); |
| HttpFSServerWebApp.get().get(DelegationTokenManager.class).verifyToken(dToken); |
| } |
| |
| @Test |
| @TestDir |
| public void testAuthenticate() throws Exception { |
| String dir = TestDirHelper.getTestDir().getAbsolutePath(); |
| |
| Configuration httpfsConf = new Configuration(false); |
| HttpFSServerWebApp server = |
| new HttpFSServerWebApp(dir, dir, dir, dir, httpfsConf); |
| server.setAuthority(new InetSocketAddress(InetAddress.getLocalHost(), |
| 14000)); |
| AuthenticationHandler handler = |
| new HttpFSKerberosAuthenticationHandlerForTesting(); |
| try { |
| server.init(); |
| handler.init(null); |
| |
| testValidDelegationToken(handler); |
| testInvalidDelegationToken(handler); |
| } finally { |
| if (handler != null) { |
| handler.destroy(); |
| } |
| server.destroy(); |
| } |
| } |
| |
| private void testValidDelegationToken(AuthenticationHandler handler) |
| throws Exception { |
| HttpServletRequest request = Mockito.mock(HttpServletRequest.class); |
| HttpServletResponse response = Mockito.mock(HttpServletResponse.class); |
| Token<DelegationTokenIdentifier> dToken = |
| HttpFSServerWebApp.get().get(DelegationTokenManager.class).createToken( |
| UserGroupInformation.getCurrentUser(), "user"); |
| Mockito.when(request.getParameter(HttpFSKerberosAuthenticator.DELEGATION_PARAM)). |
| thenReturn(dToken.encodeToUrlString()); |
| |
| AuthenticationToken token = handler.authenticate(request, response); |
| Assert.assertEquals(UserGroupInformation.getCurrentUser().getShortUserName(), |
| token.getUserName()); |
| Assert.assertEquals(0, token.getExpires()); |
| Assert.assertEquals(HttpFSKerberosAuthenticationHandler.TYPE, |
| token.getType()); |
| Assert.assertTrue(token.isExpired()); |
| } |
| |
| private void testInvalidDelegationToken(AuthenticationHandler handler) |
| throws Exception { |
| HttpServletRequest request = Mockito.mock(HttpServletRequest.class); |
| HttpServletResponse response = Mockito.mock(HttpServletResponse.class); |
| Mockito.when(request.getParameter(HttpFSKerberosAuthenticator.DELEGATION_PARAM)). |
| thenReturn("invalid"); |
| |
| try { |
| handler.authenticate(request, response); |
| Assert.fail(); |
| } catch (AuthenticationException ex) { |
| //NOP |
| } catch (Exception ex) { |
| Assert.fail(); |
| } |
| } |
| |
| } |