HADOOP-11181. Generalized o.a.h.s.t.d.DelegationTokenManager to handle all sub-classes of AbstractDelegationTokenIdentifier. Contributed by Zhijie Shen.

This commit is contained in:
Zhijie Shen 2014-10-14 11:35:38 -07:00
parent 7dcad84143
commit cdce88376a
9 changed files with 135 additions and 55 deletions

View File

@ -594,6 +594,10 @@ Release 2.6.0 - UNRELEASED
HADOOP-11184. Update Hadoop's lz4 to version r123. (cmccabe)
HADOOP-11181. Generalized o.a.h.s.t.d.DelegationTokenManager to handle all
sub-classes of AbstractDelegationTokenIdentifier. (zjshen)
OPTIMIZATIONS
HADOOP-10838. Byte array native checksumming. (James Thomas via todd)

View File

@ -53,26 +53,9 @@ public AbstractDelegationTokenIdentifier() {
}
public AbstractDelegationTokenIdentifier(Text owner, Text renewer, Text realUser) {
if (owner == null) {
this.owner = new Text();
} else {
this.owner = owner;
}
if (renewer == null) {
this.renewer = new Text();
} else {
HadoopKerberosName renewerKrbName = new HadoopKerberosName(renewer.toString());
try {
this.renewer = new Text(renewerKrbName.getShortName());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (realUser == null) {
this.realUser = new Text();
} else {
this.realUser = realUser;
}
setOwner(owner);
setRenewer(renewer);
setRealUser(realUser);
issueDate = 0;
maxDate = 0;
}
@ -107,14 +90,43 @@ public Text getOwner() {
return owner;
}
public void setOwner(Text owner) {
if (owner == null) {
this.owner = new Text();
} else {
this.owner = owner;
}
}
public Text getRenewer() {
return renewer;
}
public void setRenewer(Text renewer) {
if (renewer == null) {
this.renewer = new Text();
} else {
HadoopKerberosName renewerKrbName = new HadoopKerberosName(renewer.toString());
try {
this.renewer = new Text(renewerKrbName.getShortName());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public Text getRealUser() {
return realUser;
}
public void setRealUser(Text realUser) {
if (realUser == null) {
this.realUser = new Text();
} else {
this.realUser = realUser;
}
}
public void setIssueDate(long issueDate) {
this.issueDate = issueDate;
}

View File

@ -648,4 +648,17 @@ public void run() {
}
}
}
/**
* Decode the token identifier. The subclass can customize the way to decode
* the token identifier.
*
* @param token the token where to extract the identifier
* @return the delegation token identifier
* @throws IOException
*/
public TokenIdent decodeTokenIdentifier(Token<TokenIdent> token) throws IOException {
return token.decodeIdentifier();
}
}

View File

@ -28,6 +28,7 @@
import org.apache.hadoop.security.authentication.server.AuthenticationToken;
import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenIdentifier;
import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenSecretManager;
import org.apache.hadoop.util.HttpExceptionUtils;
import org.codehaus.jackson.map.ObjectMapper;
@ -216,8 +217,7 @@ public boolean managementOperation(AuthenticationToken token,
);
requestContinues = false;
} else {
Token<DelegationTokenIdentifier> dt =
new Token<DelegationTokenIdentifier>();
Token<AbstractDelegationTokenIdentifier> dt = new Token();
try {
dt.decodeFromUrlString(tokenToRenew);
long expirationTime = tokenManager.renewToken(dt,
@ -240,8 +240,7 @@ public boolean managementOperation(AuthenticationToken token,
);
requestContinues = false;
} else {
Token<DelegationTokenIdentifier> dt =
new Token<DelegationTokenIdentifier>();
Token<AbstractDelegationTokenIdentifier> dt = new Token();
try {
dt.decodeFromUrlString(tokenToCancel);
tokenManager.cancelToken(dt, (requestUgi != null)
@ -303,6 +302,7 @@ private static Map delegationTokenToJSON(Token token) throws IOException {
* @throws IOException thrown if an IO error occurred.
* @throws AuthenticationException thrown if the authentication failed.
*/
@SuppressWarnings("unchecked")
@Override
public AuthenticationToken authenticate(HttpServletRequest request,
HttpServletResponse response)
@ -311,8 +311,7 @@ public AuthenticationToken authenticate(HttpServletRequest request,
String delegationParam = getDelegationToken(request);
if (delegationParam != null) {
try {
Token<DelegationTokenIdentifier> dt =
new Token<DelegationTokenIdentifier>();
Token<AbstractDelegationTokenIdentifier> dt = new Token();
dt.decodeFromUrlString(delegationParam);
UserGroupInformation ugi = tokenManager.verifyToken(dt);
final String shortName = ugi.getShortUserName();

View File

@ -27,6 +27,7 @@
import org.apache.hadoop.io.Text;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenIdentifier;
import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenSecretManager;
import org.apache.hadoop.security.token.delegation.ZKDelegationTokenSecretManager;
@ -76,6 +77,13 @@ public DelegationTokenSecretManager(Configuration conf, Text tokenKind) {
public DelegationTokenIdentifier createIdentifier() {
return new DelegationTokenIdentifier(tokenKind);
}
@Override
public DelegationTokenIdentifier decodeTokenIdentifier(
Token<DelegationTokenIdentifier> token) throws IOException {
return DelegationTokenManager.decodeToken(token, tokenKind);
}
}
private static class ZKSecretManager
@ -92,11 +100,16 @@ public ZKSecretManager(Configuration conf, Text tokenKind) {
public DelegationTokenIdentifier createIdentifier() {
return new DelegationTokenIdentifier(tokenKind);
}
@Override
public DelegationTokenIdentifier decodeTokenIdentifier(
Token<DelegationTokenIdentifier> token) throws IOException {
return DelegationTokenManager.decodeToken(token, tokenKind);
}
}
private AbstractDelegationTokenSecretManager secretManager = null;
private boolean managedSecretManager;
private Text tokenKind;
public DelegationTokenManager(Configuration conf, Text tokenKind) {
if (conf.getBoolean(ENABLE_ZK_KEY, false)) {
@ -104,7 +117,6 @@ public DelegationTokenManager(Configuration conf, Text tokenKind) {
} else {
this.secretManager = new DelegationTokenSecretManager(conf, tokenKind);
}
this.tokenKind = tokenKind;
managedSecretManager = true;
}
@ -121,7 +133,6 @@ public void setExternalDelegationTokenSecretManager(
AbstractDelegationTokenSecretManager secretManager) {
this.secretManager.stopThreads();
this.secretManager = secretManager;
this.tokenKind = secretManager.createIdentifier().getKind();
managedSecretManager = false;
}
@ -143,8 +154,8 @@ public void destroy() {
}
@SuppressWarnings("unchecked")
public Token<DelegationTokenIdentifier> createToken(UserGroupInformation ugi,
String renewer) {
public Token<? extends AbstractDelegationTokenIdentifier> createToken(
UserGroupInformation ugi, String renewer) {
renewer = (renewer == null) ? ugi.getShortUserName() : renewer;
String user = ugi.getUserName();
Text owner = new Text(user);
@ -152,19 +163,24 @@ public Token<DelegationTokenIdentifier> createToken(UserGroupInformation ugi,
if (ugi.getRealUser() != null) {
realUser = new Text(ugi.getRealUser().getUserName());
}
DelegationTokenIdentifier tokenIdentifier = new DelegationTokenIdentifier(
tokenKind, owner, new Text(renewer), realUser);
return new Token<DelegationTokenIdentifier>(tokenIdentifier, secretManager);
AbstractDelegationTokenIdentifier tokenIdentifier =
(AbstractDelegationTokenIdentifier) secretManager.createIdentifier();
tokenIdentifier.setOwner(owner);
tokenIdentifier.setRenewer(new Text(renewer));
tokenIdentifier.setRealUser(realUser);
return new Token(tokenIdentifier, secretManager);
}
@SuppressWarnings("unchecked")
public long renewToken(Token<DelegationTokenIdentifier> token, String renewer)
throws IOException {
public long renewToken(
Token<? extends AbstractDelegationTokenIdentifier> token, String renewer)
throws IOException {
return secretManager.renewToken(token, renewer);
}
@SuppressWarnings("unchecked")
public void cancelToken(Token<DelegationTokenIdentifier> token,
public void cancelToken(
Token<? extends AbstractDelegationTokenIdentifier> token,
String canceler) throws IOException {
canceler = (canceler != null) ? canceler :
verifyToken(token).getShortUserName();
@ -172,13 +188,10 @@ public void cancelToken(Token<DelegationTokenIdentifier> token,
}
@SuppressWarnings("unchecked")
public UserGroupInformation verifyToken(Token<DelegationTokenIdentifier>
token) throws IOException {
ByteArrayInputStream buf = new ByteArrayInputStream(token.getIdentifier());
DataInputStream dis = new DataInputStream(buf);
DelegationTokenIdentifier id = new DelegationTokenIdentifier(tokenKind);
id.readFields(dis);
dis.close();
public UserGroupInformation verifyToken(
Token<? extends AbstractDelegationTokenIdentifier> token)
throws IOException {
AbstractDelegationTokenIdentifier id = secretManager.decodeTokenIdentifier(token);
secretManager.verifyToken(id, token.getPassword());
return id.getUser();
}
@ -188,4 +201,15 @@ public UserGroupInformation verifyToken(Token<DelegationTokenIdentifier>
public AbstractDelegationTokenSecretManager getDelegationTokenSecretManager() {
return secretManager;
}
private static DelegationTokenIdentifier decodeToken(
Token<DelegationTokenIdentifier> token, Text tokenKind)
throws IOException {
ByteArrayInputStream buf = new ByteArrayInputStream(token.getIdentifier());
DataInputStream dis = new DataInputStream(buf);
DelegationTokenIdentifier id = new DelegationTokenIdentifier(tokenKind);
id.readFields(dis);
dis.close();
return id;
}
}

View File

@ -32,6 +32,7 @@ public class TestZKDelegationTokenSecretManager {
private static final long DAY_IN_SECS = 86400;
@SuppressWarnings("unchecked")
@Test
public void testZKDelTokSecretManager() throws Exception {
TestingServer zkServer = new TestingServer();
@ -54,11 +55,13 @@ public void testZKDelTokSecretManager() throws Exception {
tm2.init();
Token<DelegationTokenIdentifier> token =
tm1.createToken(UserGroupInformation.getCurrentUser(), "foo");
(Token<DelegationTokenIdentifier>) tm1.createToken(
UserGroupInformation.getCurrentUser(), "foo");
Assert.assertNotNull(token);
tm2.verifyToken(token);
token = tm2.createToken(UserGroupInformation.getCurrentUser(), "bar");
token = (Token<DelegationTokenIdentifier>) tm2.createToken(
UserGroupInformation.getCurrentUser(), "bar");
Assert.assertNotNull(token);
tm1.verifyToken(token);
} finally {

View File

@ -202,6 +202,7 @@ private void testGetToken(String renewer, Text expectedTokenKind)
Assert.assertEquals(expectedTokenKind, dt.getKind());
}
@SuppressWarnings("unchecked")
private void testCancelToken() throws Exception {
DelegationTokenAuthenticator.DelegationTokenOperation op =
DelegationTokenAuthenticator.DelegationTokenOperation.
@ -220,7 +221,7 @@ private void testCancelToken() throws Exception {
Mockito.reset(response);
Token<DelegationTokenIdentifier> token =
handler.getTokenManager().createToken(
(Token<DelegationTokenIdentifier>) handler.getTokenManager().createToken(
UserGroupInformation.getCurrentUser(), "foo");
Mockito.when(request.getQueryString()).thenReturn(
DelegationTokenAuthenticator.OP_PARAM + "=" + op.toString() + "&" +
@ -239,6 +240,7 @@ private void testCancelToken() throws Exception {
}
}
@SuppressWarnings("unchecked")
private void testRenewToken() throws Exception {
DelegationTokenAuthenticator.DelegationTokenOperation op =
DelegationTokenAuthenticator.DelegationTokenOperation.
@ -271,7 +273,7 @@ private void testRenewToken() throws Exception {
PrintWriter pwriter = new PrintWriter(writer);
Mockito.when(response.getWriter()).thenReturn(pwriter);
Token<DelegationTokenIdentifier> dToken =
handler.getTokenManager().createToken(
(Token<DelegationTokenIdentifier>) handler.getTokenManager().createToken(
UserGroupInformation.getCurrentUser(), "user");
Mockito.when(request.getQueryString()).
thenReturn(DelegationTokenAuthenticator.OP_PARAM + "=" + op.toString() +
@ -292,11 +294,12 @@ public void testAuthenticate() throws Exception {
testInvalidDelegationTokenHeader();
}
@SuppressWarnings("unchecked")
private void testValidDelegationTokenQueryString() throws Exception {
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
Token<DelegationTokenIdentifier> dToken =
handler.getTokenManager().createToken(
(Token<DelegationTokenIdentifier>) handler.getTokenManager().createToken(
UserGroupInformation.getCurrentUser(), "user");
Mockito.when(request.getQueryString()).thenReturn(
DelegationTokenAuthenticator.DELEGATION_PARAM + "=" +
@ -311,11 +314,12 @@ private void testValidDelegationTokenQueryString() throws Exception {
Assert.assertTrue(token.isExpired());
}
@SuppressWarnings("unchecked")
private void testValidDelegationTokenHeader() throws Exception {
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
Token<DelegationTokenIdentifier> dToken =
handler.getTokenManager().createToken(
(Token<DelegationTokenIdentifier>) handler.getTokenManager().createToken(
UserGroupInformation.getCurrentUser(), "user");
Mockito.when(request.getHeader(Mockito.eq(
DelegationTokenAuthenticator.DELEGATION_TOKEN_HEADER))).thenReturn(

View File

@ -18,6 +18,8 @@
package org.apache.hadoop.security.token.delegation.web;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.Text;
@ -25,11 +27,26 @@
import org.apache.hadoop.security.token.Token;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class TestDelegationTokenManager {
private static final long DAY_IN_SECS = 86400;
@Parameterized.Parameters
public static Collection<Object[]> headers() {
return Arrays.asList(new Object[][] { { false }, { true } });
}
private boolean enableZKKey;
public TestDelegationTokenManager(boolean enableZKKey) {
this.enableZKKey = enableZKKey;
}
@SuppressWarnings("unchecked")
@Test
public void testDTManager() throws Exception {
Configuration conf = new Configuration(false);
@ -37,11 +54,13 @@ public void testDTManager() throws Exception {
conf.setLong(DelegationTokenManager.MAX_LIFETIME, DAY_IN_SECS);
conf.setLong(DelegationTokenManager.RENEW_INTERVAL, DAY_IN_SECS);
conf.setLong(DelegationTokenManager.REMOVAL_SCAN_INTERVAL, DAY_IN_SECS);
conf.getBoolean(DelegationTokenManager.ENABLE_ZK_KEY, enableZKKey);
DelegationTokenManager tm =
new DelegationTokenManager(conf, new Text("foo"));
tm.init();
Token<DelegationTokenIdentifier> token =
tm.createToken(UserGroupInformation.getCurrentUser(), "foo");
(Token<DelegationTokenIdentifier>) tm.createToken(
UserGroupInformation.getCurrentUser(), "foo");
Assert.assertNotNull(token);
tm.verifyToken(token);
Assert.assertTrue(tm.renewToken(token, "foo") > System.currentTimeMillis());

View File

@ -738,7 +738,8 @@ private void assertValidRMToken(String encodedToken) throws IOException {
Token<RMDelegationTokenIdentifier> realToken =
new Token<RMDelegationTokenIdentifier>();
realToken.decodeFromUrlString(encodedToken);
RMDelegationTokenIdentifier ident = realToken.decodeIdentifier();
RMDelegationTokenIdentifier ident = rm.getRMContext()
.getRMDelegationTokenSecretManager().decodeTokenIdentifier(realToken);
rm.getRMContext().getRMDelegationTokenSecretManager()
.verifyToken(ident, realToken.getPassword());
assertTrue(rm.getRMContext().getRMDelegationTokenSecretManager()
@ -749,7 +750,8 @@ private void assertTokenCancelled(String encodedToken) throws Exception {
Token<RMDelegationTokenIdentifier> realToken =
new Token<RMDelegationTokenIdentifier>();
realToken.decodeFromUrlString(encodedToken);
RMDelegationTokenIdentifier ident = realToken.decodeIdentifier();
RMDelegationTokenIdentifier ident = rm.getRMContext()
.getRMDelegationTokenSecretManager().decodeTokenIdentifier(realToken);
boolean exceptionCaught = false;
try {
rm.getRMContext().getRMDelegationTokenSecretManager()