HADOOP-13346. DelegationTokenAuthenticationHandler writes via closed writer. Contributed by Gregory Chanan and Hrishikesh Gadre.
This commit is contained in:
parent
c619e9b43f
commit
822ae88f7d
@ -48,6 +48,8 @@
|
||||
import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenSecretManager;
|
||||
import org.apache.hadoop.util.HttpExceptionUtils;
|
||||
import org.apache.hadoop.util.StringUtils;
|
||||
import org.codehaus.jackson.JsonFactory;
|
||||
import org.codehaus.jackson.JsonGenerator;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
@ -89,6 +91,8 @@ public abstract class DelegationTokenAuthenticationHandler
|
||||
public static final String DELEGATION_TOKEN_UGI_ATTRIBUTE =
|
||||
"hadoop.security.delegation-token.ugi";
|
||||
|
||||
public static final String JSON_MAPPER_PREFIX = PREFIX + "json-mapper.";
|
||||
|
||||
static {
|
||||
DELEGATION_TOKEN_OPS.add(KerberosDelegationTokenAuthenticator.
|
||||
DelegationTokenOperation.GETDELEGATIONTOKEN.toString());
|
||||
@ -101,6 +105,7 @@ public abstract class DelegationTokenAuthenticationHandler
|
||||
private AuthenticationHandler authHandler;
|
||||
private DelegationTokenManager tokenManager;
|
||||
private String authType;
|
||||
private JsonFactory jsonFactory;
|
||||
|
||||
public DelegationTokenAuthenticationHandler(AuthenticationHandler handler) {
|
||||
authHandler = handler;
|
||||
@ -120,6 +125,7 @@ AuthenticationHandler getAuthHandler() {
|
||||
public void init(Properties config) throws ServletException {
|
||||
authHandler.init(config);
|
||||
initTokenManager(config);
|
||||
initJsonFactory(config);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -153,6 +159,30 @@ public void initTokenManager(Properties config) {
|
||||
tokenManager.init();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void initJsonFactory(Properties config) {
|
||||
boolean hasFeature = false;
|
||||
JsonFactory tmpJsonFactory = new JsonFactory();
|
||||
|
||||
for (Map.Entry entry : config.entrySet()) {
|
||||
String key = (String)entry.getKey();
|
||||
if (key.startsWith(JSON_MAPPER_PREFIX)) {
|
||||
JsonGenerator.Feature feature =
|
||||
JsonGenerator.Feature.valueOf(key.substring(JSON_MAPPER_PREFIX
|
||||
.length()));
|
||||
if (feature != null) {
|
||||
hasFeature = true;
|
||||
boolean enabled = Boolean.parseBoolean((String)entry.getValue());
|
||||
tmpJsonFactory.configure(feature, enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasFeature) {
|
||||
jsonFactory = tmpJsonFactory;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
tokenManager.destroy();
|
||||
@ -298,7 +328,7 @@ public boolean managementOperation(AuthenticationToken token,
|
||||
if (map != null) {
|
||||
response.setContentType(MediaType.APPLICATION_JSON);
|
||||
Writer writer = response.getWriter();
|
||||
ObjectMapper jsonMapper = new ObjectMapper();
|
||||
ObjectMapper jsonMapper = new ObjectMapper(jsonFactory);
|
||||
jsonMapper.writeValue(writer, map);
|
||||
writer.write(ENTER);
|
||||
writer.flush();
|
||||
|
@ -17,6 +17,9 @@
|
||||
*/
|
||||
package org.apache.hadoop.security.token.delegation.web;
|
||||
|
||||
import static org.apache.hadoop.security.token.delegation.web.DelegationTokenAuthenticator.DelegationTokenOperation.*;
|
||||
|
||||
import org.apache.commons.lang.mutable.MutableBoolean;
|
||||
import org.apache.hadoop.io.Text;
|
||||
import org.apache.hadoop.security.UserGroupInformation;
|
||||
import org.apache.hadoop.security.authentication.client.AuthenticationException;
|
||||
@ -458,4 +461,51 @@ public void testCannotRenewTokenUsingToken() throws Exception {
|
||||
Assert.assertFalse(handler.managementOperation(null, request, response));
|
||||
Mockito.verify(response).setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriterNotClosed() throws Exception {
|
||||
Properties conf = new Properties();
|
||||
conf.put(KerberosDelegationTokenAuthenticationHandler.TOKEN_KIND, "foo");
|
||||
conf.put(DelegationTokenAuthenticationHandler.JSON_MAPPER_PREFIX
|
||||
+ "AUTO_CLOSE_TARGET", "false");
|
||||
DelegationTokenAuthenticationHandler noAuthCloseHandler =
|
||||
new MockDelegationTokenAuthenticationHandler();
|
||||
try {
|
||||
noAuthCloseHandler.initTokenManager(conf);
|
||||
noAuthCloseHandler.initJsonFactory(conf);
|
||||
|
||||
DelegationTokenAuthenticator.DelegationTokenOperation op =
|
||||
GETDELEGATIONTOKEN;
|
||||
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
|
||||
HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
|
||||
Mockito.when(request.getQueryString()).thenReturn(
|
||||
DelegationTokenAuthenticator.OP_PARAM + "=" + op.toString());
|
||||
Mockito.when(request.getMethod()).thenReturn(op.getHttpMethod());
|
||||
|
||||
AuthenticationToken token = Mockito.mock(AuthenticationToken.class);
|
||||
Mockito.when(token.getUserName()).thenReturn("user");
|
||||
final MutableBoolean closed = new MutableBoolean();
|
||||
PrintWriter printWriterCloseCount = new PrintWriter(new StringWriter()) {
|
||||
@Override
|
||||
public void close() {
|
||||
closed.setValue(true);
|
||||
super.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(String str) {
|
||||
if (closed.booleanValue()) {
|
||||
throw new RuntimeException("already closed!");
|
||||
}
|
||||
super.write(str);
|
||||
}
|
||||
|
||||
};
|
||||
Mockito.when(response.getWriter()).thenReturn(printWriterCloseCount);
|
||||
Assert.assertFalse(noAuthCloseHandler.managementOperation(token, request,
|
||||
response));
|
||||
} finally {
|
||||
noAuthCloseHandler.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user