You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by rk...@apache.org on 2015/02/13 23:18:20 UTC
hadoop git commit: HADOOP-11467. KerberosAuthenticator can connect to
a non-secure cluster. (yzhangal via rkanter)
Repository: hadoop
Updated Branches:
refs/heads/trunk 1a0f508b6 -> 875256834
HADOOP-11467. KerberosAuthenticator can connect to a non-secure cluster. (yzhangal via rkanter)
Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/87525683
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/87525683
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/87525683
Branch: refs/heads/trunk
Commit: 875256834b892b574499d5fe68f95a9aed244f7d
Parents: 1a0f508
Author: Robert Kanter <rk...@apache.org>
Authored: Fri Feb 13 14:01:46 2015 -0800
Committer: Robert Kanter <rk...@apache.org>
Committed: Fri Feb 13 14:01:46 2015 -0800
----------------------------------------------------------------------
.../client/KerberosAuthenticator.java | 26 ++-
.../server/AuthenticationToken.java | 162 ++------------
.../security/authentication/util/AuthToken.java | 218 +++++++++++++++++++
.../server/TestAuthenticationToken.java | 100 ---------
.../authentication/util/TestAuthToken.java | 127 +++++++++++
hadoop-common-project/hadoop-common/CHANGES.txt | 3 +
6 files changed, 385 insertions(+), 251 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hadoop/blob/87525683/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/client/KerberosAuthenticator.java
----------------------------------------------------------------------
diff --git a/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/client/KerberosAuthenticator.java b/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/client/KerberosAuthenticator.java
index 323b019..e107810 100644
--- a/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/client/KerberosAuthenticator.java
+++ b/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/client/KerberosAuthenticator.java
@@ -14,6 +14,7 @@
package org.apache.hadoop.security.authentication.client;
import org.apache.commons.codec.binary.Base64;
+import org.apache.hadoop.security.authentication.util.AuthToken;
import org.apache.hadoop.security.authentication.util.KerberosUtil;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSManager;
@@ -29,6 +30,7 @@ import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
+
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
@@ -187,13 +189,18 @@ public class KerberosAuthenticator implements Authenticator {
conn.setRequestMethod(AUTH_HTTP_METHOD);
conn.connect();
+ boolean needFallback = false;
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
LOG.debug("JDK performed authentication on our behalf.");
// If the JDK already did the SPNEGO back-and-forth for
// us, just pull out the token.
AuthenticatedURL.extractToken(conn, token);
- return;
- } else if (isNegotiate()) {
+ if (isTokenKerberos(token)) {
+ return;
+ }
+ needFallback = true;
+ }
+ if (!needFallback && isNegotiate()) {
LOG.debug("Performing our own SPNEGO sequence.");
doSpnegoSequence(token);
} else {
@@ -225,6 +232,21 @@ public class KerberosAuthenticator implements Authenticator {
}
/*
+ * Check if the passed token is of type "kerberos" or "kerberos-dt"
+ */
+ private boolean isTokenKerberos(AuthenticatedURL.Token token)
+ throws AuthenticationException {
+ if (token.isSet()) {
+ AuthToken aToken = AuthToken.parse(token.toString());
+ if (aToken.getType().equals("kerberos") ||
+ aToken.getType().equals("kerberos-dt")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /*
* Indicates if the response is starting a SPNEGO negotiation.
*/
private boolean isNegotiate() throws IOException {
http://git-wip-us.apache.org/repos/asf/hadoop/blob/87525683/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationToken.java
----------------------------------------------------------------------
diff --git a/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationToken.java b/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationToken.java
index bb3e71d..0e2b45d 100644
--- a/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationToken.java
+++ b/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationToken.java
@@ -14,14 +14,9 @@
package org.apache.hadoop.security.authentication.server;
import org.apache.hadoop.security.authentication.client.AuthenticationException;
+import org.apache.hadoop.security.authentication.util.AuthToken;
import java.security.Principal;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
import javax.servlet.http.HttpServletRequest;
@@ -34,38 +29,21 @@ import javax.servlet.http.HttpServletRequest;
* and received in HTTP client responses and requests as a HTTP cookie (this is
* done by the {@link AuthenticationFilter}).
*/
-public class AuthenticationToken implements Principal {
+public class AuthenticationToken extends AuthToken {
/**
* Constant that identifies an anonymous request.
*/
public static final AuthenticationToken ANONYMOUS = new AuthenticationToken();
- private static final String ATTR_SEPARATOR = "&";
- private static final String USER_NAME = "u";
- private static final String PRINCIPAL = "p";
- private static final String EXPIRES = "e";
- private static final String TYPE = "t";
-
- private final static Set<String> ATTRIBUTES =
- new HashSet<String>(Arrays.asList(USER_NAME, PRINCIPAL, EXPIRES, TYPE));
-
- private String userName;
- private String principal;
- private String type;
- private long expires;
- private String token;
-
private AuthenticationToken() {
- userName = null;
- principal = null;
- type = null;
- expires = -1;
- token = "ANONYMOUS";
- generateToken();
+ super();
}
- private static final String ILLEGAL_ARG_MSG = " is NULL, empty or contains a '" + ATTR_SEPARATOR + "'";
+ private AuthenticationToken(AuthToken token) {
+ super(token.getUserName(), token.getName(), token.getType());
+ setExpires(token.getExpires());
+ }
/**
* Creates an authentication token.
@@ -77,25 +55,7 @@ public class AuthenticationToken implements Principal {
* (<code>System.currentTimeMillis() + validityPeriod</code>).
*/
public AuthenticationToken(String userName, String principal, String type) {
- checkForIllegalArgument(userName, "userName");
- checkForIllegalArgument(principal, "principal");
- checkForIllegalArgument(type, "type");
- this.userName = userName;
- this.principal = principal;
- this.type = type;
- this.expires = -1;
- }
-
- /**
- * Check if the provided value is invalid. Throw an error if it is invalid, NOP otherwise.
- *
- * @param value the value to check.
- * @param name the parameter name to use in an error message if the value is invalid.
- */
- private static void checkForIllegalArgument(String value, String name) {
- if (value == null || value.length() == 0 || value.contains(ATTR_SEPARATOR)) {
- throw new IllegalArgumentException(name + ILLEGAL_ARG_MSG);
- }
+ super(userName, principal, type);
}
/**
@@ -105,79 +65,17 @@ public class AuthenticationToken implements Principal {
*/
public void setExpires(long expires) {
if (this != AuthenticationToken.ANONYMOUS) {
- this.expires = expires;
- generateToken();
+ super.setExpires(expires);
}
}
/**
- * Generates the token.
- */
- private void generateToken() {
- StringBuffer sb = new StringBuffer();
- sb.append(USER_NAME).append("=").append(getUserName()).append(ATTR_SEPARATOR);
- sb.append(PRINCIPAL).append("=").append(getName()).append(ATTR_SEPARATOR);
- sb.append(TYPE).append("=").append(getType()).append(ATTR_SEPARATOR);
- sb.append(EXPIRES).append("=").append(getExpires());
- token = sb.toString();
- }
-
- /**
- * Returns the user name.
- *
- * @return the user name.
- */
- public String getUserName() {
- return userName;
- }
-
- /**
- * Returns the principal name (this method name comes from the JDK {@link Principal} interface).
- *
- * @return the principal name.
- */
- @Override
- public String getName() {
- return principal;
- }
-
- /**
- * Returns the authentication mechanism of the token.
- *
- * @return the authentication mechanism of the token.
- */
- public String getType() {
- return type;
- }
-
- /**
- * Returns the expiration time of the token.
- *
- * @return the expiration time of the token, in milliseconds since Epoc.
- */
- public long getExpires() {
- return expires;
- }
-
- /**
- * Returns if the token has expired.
+ * Returns true if the token has expired.
*
- * @return if the token has expired.
+ * @return true if the token has expired.
*/
public boolean isExpired() {
- return getExpires() != -1 && System.currentTimeMillis() > getExpires();
- }
-
- /**
- * Returns the string representation of the token.
- * <p>
- * This string representation is parseable by the {@link #parse} method.
- *
- * @return the string representation of the token.
- */
- @Override
- public String toString() {
- return token;
+ return super.isExpired();
}
/**
@@ -191,40 +89,6 @@ public class AuthenticationToken implements Principal {
* an authentication token.
*/
public static AuthenticationToken parse(String tokenStr) throws AuthenticationException {
- Map<String, String> map = split(tokenStr);
- if (!map.keySet().equals(ATTRIBUTES)) {
- throw new AuthenticationException("Invalid token string, missing attributes");
- }
- long expires = Long.parseLong(map.get(EXPIRES));
- AuthenticationToken token = new AuthenticationToken(map.get(USER_NAME), map.get(PRINCIPAL), map.get(TYPE));
- token.setExpires(expires);
- return token;
- }
-
- /**
- * Splits the string representation of a token into attributes pairs.
- *
- * @param tokenStr string representation of a token.
- *
- * @return a map with the attribute pairs of the token.
- *
- * @throws AuthenticationException thrown if the string representation of the token could not be broken into
- * attribute pairs.
- */
- private static Map<String, String> split(String tokenStr) throws AuthenticationException {
- Map<String, String> map = new HashMap<String, String>();
- StringTokenizer st = new StringTokenizer(tokenStr, ATTR_SEPARATOR);
- while (st.hasMoreTokens()) {
- String part = st.nextToken();
- int separator = part.indexOf('=');
- if (separator == -1) {
- throw new AuthenticationException("Invalid authentication token");
- }
- String key = part.substring(0, separator);
- String value = part.substring(separator + 1);
- map.put(key, value);
- }
- return map;
+ return new AuthenticationToken(AuthToken.parse(tokenStr));
}
-
}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/87525683/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/AuthToken.java
----------------------------------------------------------------------
diff --git a/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/AuthToken.java b/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/AuthToken.java
new file mode 100644
index 0000000..7269eb2
--- /dev/null
+++ b/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/AuthToken.java
@@ -0,0 +1,218 @@
+/**
+ * Licensed 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. See accompanying LICENSE file.
+ */
+package org.apache.hadoop.security.authentication.util;
+
+import org.apache.hadoop.security.authentication.client.AuthenticationException;
+
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ */
+public class AuthToken implements Principal {
+
+ /**
+ * Constant that identifies an anonymous request.
+ */
+
+ private static final String ATTR_SEPARATOR = "&";
+ private static final String USER_NAME = "u";
+ private static final String PRINCIPAL = "p";
+ private static final String EXPIRES = "e";
+ private static final String TYPE = "t";
+
+ private final static Set<String> ATTRIBUTES =
+ new HashSet<String>(Arrays.asList(USER_NAME, PRINCIPAL, EXPIRES, TYPE));
+
+ private String userName;
+ private String principal;
+ private String type;
+ private long expires;
+ private String tokenStr;
+
+ protected AuthToken() {
+ userName = null;
+ principal = null;
+ type = null;
+ expires = -1;
+ tokenStr = "ANONYMOUS";
+ generateToken();
+ }
+
+ private static final String ILLEGAL_ARG_MSG = " is NULL, empty or contains a '" + ATTR_SEPARATOR + "'";
+
+ /**
+ * Creates an authentication token.
+ *
+ * @param userName user name.
+ * @param principal principal (commonly matches the user name, with Kerberos is the full/long principal
+ * name while the userName is the short name).
+ * @param type the authentication mechanism name.
+ * (<code>System.currentTimeMillis() + validityPeriod</code>).
+ */
+ public AuthToken(String userName, String principal, String type) {
+ checkForIllegalArgument(userName, "userName");
+ checkForIllegalArgument(principal, "principal");
+ checkForIllegalArgument(type, "type");
+ this.userName = userName;
+ this.principal = principal;
+ this.type = type;
+ this.expires = -1;
+ }
+
+ /**
+ * Check if the provided value is invalid. Throw an error if it is invalid, NOP otherwise.
+ *
+ * @param value the value to check.
+ * @param name the parameter name to use in an error message if the value is invalid.
+ */
+ protected static void checkForIllegalArgument(String value, String name) {
+ if (value == null || value.length() == 0 || value.contains(ATTR_SEPARATOR)) {
+ throw new IllegalArgumentException(name + ILLEGAL_ARG_MSG);
+ }
+ }
+
+ /**
+ * Sets the expiration of the token.
+ *
+ * @param expires expiration time of the token in milliseconds since the epoch.
+ */
+ public void setExpires(long expires) {
+ this.expires = expires;
+ generateToken();
+ }
+
+ /**
+ * Returns true if the token has expired.
+ *
+ * @return true if the token has expired.
+ */
+ public boolean isExpired() {
+ return getExpires() != -1 && System.currentTimeMillis() > getExpires();
+ }
+
+ /**
+ * Generates the token.
+ */
+ private void generateToken() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(USER_NAME).append("=").append(getUserName()).append(ATTR_SEPARATOR);
+ sb.append(PRINCIPAL).append("=").append(getName()).append(ATTR_SEPARATOR);
+ sb.append(TYPE).append("=").append(getType()).append(ATTR_SEPARATOR);
+ sb.append(EXPIRES).append("=").append(getExpires());
+ tokenStr = sb.toString();
+ }
+
+ /**
+ * Returns the user name.
+ *
+ * @return the user name.
+ */
+ public String getUserName() {
+ return userName;
+ }
+
+ /**
+ * Returns the principal name (this method name comes from the JDK {@link Principal} interface).
+ *
+ * @return the principal name.
+ */
+ @Override
+ public String getName() {
+ return principal;
+ }
+
+ /**
+ * Returns the authentication mechanism of the token.
+ *
+ * @return the authentication mechanism of the token.
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * Returns the expiration time of the token.
+ *
+ * @return the expiration time of the token, in milliseconds since Epoc.
+ */
+ public long getExpires() {
+ return expires;
+ }
+
+ /**
+ * Returns the string representation of the token.
+ * <p>
+ * This string representation is parseable by the {@link #parse} method.
+ *
+ * @return the string representation of the token.
+ */
+ @Override
+ public String toString() {
+ return tokenStr;
+ }
+
+ public static AuthToken parse(String tokenStr) throws AuthenticationException {
+ if (tokenStr.length() >= 2) {
+ // strip the \" at the two ends of the tokenStr
+ if (tokenStr.charAt(0) == '\"' &&
+ tokenStr.charAt(tokenStr.length()-1) == '\"') {
+ tokenStr = tokenStr.substring(1, tokenStr.length()-1);
+ }
+ }
+ Map<String, String> map = split(tokenStr);
+ // remove the signature part, since client doesn't care about it
+ map.remove("s");
+
+ if (!map.keySet().equals(ATTRIBUTES)) {
+ throw new AuthenticationException("Invalid token string, missing attributes");
+ }
+ long expires = Long.parseLong(map.get(EXPIRES));
+ AuthToken token = new AuthToken(map.get(USER_NAME), map.get(PRINCIPAL), map.get(TYPE));
+ token.setExpires(expires);
+ return token;
+ }
+
+ /**
+ * Splits the string representation of a token into attributes pairs.
+ *
+ * @param tokenStr string representation of a token.
+ *
+ * @return a map with the attribute pairs of the token.
+ *
+ * @throws AuthenticationException thrown if the string representation of the token could not be broken into
+ * attribute pairs.
+ */
+ private static Map<String, String> split(String tokenStr) throws AuthenticationException {
+ Map<String, String> map = new HashMap<String, String>();
+ StringTokenizer st = new StringTokenizer(tokenStr, ATTR_SEPARATOR);
+ while (st.hasMoreTokens()) {
+ String part = st.nextToken();
+ int separator = part.indexOf('=');
+ if (separator == -1) {
+ throw new AuthenticationException("Invalid authentication token");
+ }
+ String key = part.substring(0, separator);
+ String value = part.substring(separator + 1);
+ map.put(key, value);
+ }
+ return map;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/87525683/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestAuthenticationToken.java
----------------------------------------------------------------------
diff --git a/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestAuthenticationToken.java b/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestAuthenticationToken.java
index c17c710..6727def 100644
--- a/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestAuthenticationToken.java
+++ b/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestAuthenticationToken.java
@@ -13,7 +13,6 @@
*/
package org.apache.hadoop.security.authentication.server;
-import org.apache.hadoop.security.authentication.client.AuthenticationException;
import org.junit.Assert;
import org.junit.Test;
@@ -28,103 +27,4 @@ public class TestAuthenticationToken {
Assert.assertEquals(-1, AuthenticationToken.ANONYMOUS.getExpires());
Assert.assertFalse(AuthenticationToken.ANONYMOUS.isExpired());
}
-
- @Test
- public void testConstructor() throws Exception {
- try {
- new AuthenticationToken(null, "p", "t");
- Assert.fail();
- } catch (IllegalArgumentException ex) {
- // Expected
- } catch (Throwable ex) {
- Assert.fail();
- }
- try {
- new AuthenticationToken("", "p", "t");
- Assert.fail();
- } catch (IllegalArgumentException ex) {
- // Expected
- } catch (Throwable ex) {
- Assert.fail();
- }
- try {
- new AuthenticationToken("u", null, "t");
- Assert.fail();
- } catch (IllegalArgumentException ex) {
- // Expected
- } catch (Throwable ex) {
- Assert.fail();
- }
- try {
- new AuthenticationToken("u", "", "t");
- Assert.fail();
- } catch (IllegalArgumentException ex) {
- // Expected
- } catch (Throwable ex) {
- Assert.fail();
- }
- try {
- new AuthenticationToken("u", "p", null);
- Assert.fail();
- } catch (IllegalArgumentException ex) {
- // Expected
- } catch (Throwable ex) {
- Assert.fail();
- }
- try {
- new AuthenticationToken("u", "p", "");
- Assert.fail();
- } catch (IllegalArgumentException ex) {
- // Expected
- } catch (Throwable ex) {
- Assert.fail();
- }
- new AuthenticationToken("u", "p", "t");
- }
-
- @Test
- public void testGetters() throws Exception {
- long expires = System.currentTimeMillis() + 50;
- AuthenticationToken token = new AuthenticationToken("u", "p", "t");
- token.setExpires(expires);
- Assert.assertEquals("u", token.getUserName());
- Assert.assertEquals("p", token.getName());
- Assert.assertEquals("t", token.getType());
- Assert.assertEquals(expires, token.getExpires());
- Assert.assertFalse(token.isExpired());
- Thread.sleep(70); // +20 msec fuzz for timer granularity.
- Assert.assertTrue(token.isExpired());
- }
-
- @Test
- public void testToStringAndParse() throws Exception {
- long expires = System.currentTimeMillis() + 50;
- AuthenticationToken token = new AuthenticationToken("u", "p", "t");
- token.setExpires(expires);
- String str = token.toString();
- token = AuthenticationToken.parse(str);
- Assert.assertEquals("p", token.getName());
- Assert.assertEquals("t", token.getType());
- Assert.assertEquals(expires, token.getExpires());
- Assert.assertFalse(token.isExpired());
- Thread.sleep(70); // +20 msec fuzz for timer granularity.
- Assert.assertTrue(token.isExpired());
- }
-
- @Test
- public void testParseInvalid() throws Exception {
- long expires = System.currentTimeMillis() + 50;
- AuthenticationToken token = new AuthenticationToken("u", "p", "t");
- token.setExpires(expires);
- String str = token.toString();
- str = str.substring(0, str.indexOf("e="));
- try {
- AuthenticationToken.parse(str);
- Assert.fail();
- } catch (AuthenticationException ex) {
- // Expected
- } catch (Exception ex) {
- Assert.fail();
- }
- }
}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/87525683/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/util/TestAuthToken.java
----------------------------------------------------------------------
diff --git a/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/util/TestAuthToken.java b/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/util/TestAuthToken.java
new file mode 100644
index 0000000..1cb9bf3
--- /dev/null
+++ b/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/util/TestAuthToken.java
@@ -0,0 +1,127 @@
+/**
+ * Licensed 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. See accompanying LICENSE file.
+ */
+package org.apache.hadoop.security.authentication.util;
+
+import org.apache.hadoop.security.authentication.client.AuthenticationException;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestAuthToken {
+
+ @Test
+ public void testConstructor() throws Exception {
+ try {
+ new AuthToken(null, "p", "t");
+ Assert.fail();
+ } catch (IllegalArgumentException ex) {
+ // Expected
+ } catch (Throwable ex) {
+ Assert.fail();
+ }
+ try {
+ new AuthToken("", "p", "t");
+ Assert.fail();
+ } catch (IllegalArgumentException ex) {
+ // Expected
+ } catch (Throwable ex) {
+ Assert.fail();
+ }
+ try {
+ new AuthToken("u", null, "t");
+ Assert.fail();
+ } catch (IllegalArgumentException ex) {
+ // Expected
+ } catch (Throwable ex) {
+ Assert.fail();
+ }
+ try {
+ new AuthToken("u", "", "t");
+ Assert.fail();
+ } catch (IllegalArgumentException ex) {
+ // Expected
+ } catch (Throwable ex) {
+ Assert.fail();
+ }
+ try {
+ new AuthToken("u", "p", null);
+ Assert.fail();
+ } catch (IllegalArgumentException ex) {
+ // Expected
+ } catch (Throwable ex) {
+ Assert.fail();
+ }
+ try {
+ new AuthToken("u", "p", "");
+ Assert.fail();
+ } catch (IllegalArgumentException ex) {
+ // Expected
+ } catch (Throwable ex) {
+ Assert.fail();
+ }
+ new AuthToken("u", "p", "t");
+ }
+
+ @Test
+ public void testGetters() throws Exception {
+ long expires = System.currentTimeMillis() + 50;
+ AuthToken token = new AuthToken("u", "p", "t");
+ token.setExpires(expires);
+ Assert.assertEquals("u", token.getUserName());
+ Assert.assertEquals("p", token.getName());
+ Assert.assertEquals("t", token.getType());
+ Assert.assertEquals(expires, token.getExpires());
+ Assert.assertFalse(token.isExpired());
+ Thread.sleep(70); // +20 msec fuzz for timer granularity.
+ Assert.assertTrue(token.isExpired());
+ }
+
+ @Test
+ public void testToStringAndParse() throws Exception {
+ long expires = System.currentTimeMillis() + 50;
+ AuthToken token = new AuthToken("u", "p", "t");
+ token.setExpires(expires);
+ String str = token.toString();
+ token = AuthToken.parse(str);
+ Assert.assertEquals("p", token.getName());
+ Assert.assertEquals("t", token.getType());
+ Assert.assertEquals(expires, token.getExpires());
+ Assert.assertFalse(token.isExpired());
+ Thread.sleep(70); // +20 msec fuzz for timer granularity.
+ Assert.assertTrue(token.isExpired());
+ }
+
+ @Test
+ public void testParseValidAndInvalid() throws Exception {
+ long expires = System.currentTimeMillis() + 50;
+ AuthToken token = new AuthToken("u", "p", "t");
+ token.setExpires(expires);
+ String ostr = token.toString();
+
+ String str1 = "\"" + ostr + "\"";
+ AuthToken.parse(str1);
+
+ String str2 = ostr + "&s=1234";
+ AuthToken.parse(str2);
+
+ String str = ostr.substring(0, ostr.indexOf("e="));
+ try {
+ AuthToken.parse(str);
+ Assert.fail();
+ } catch (AuthenticationException ex) {
+ // Expected
+ } catch (Exception ex) {
+ Assert.fail();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/87525683/hadoop-common-project/hadoop-common/CHANGES.txt
----------------------------------------------------------------------
diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt
index 0d8c02f..99320cb 100644
--- a/hadoop-common-project/hadoop-common/CHANGES.txt
+++ b/hadoop-common-project/hadoop-common/CHANGES.txt
@@ -928,6 +928,9 @@ Release 2.7.0 - UNRELEASED
HADOOP-11587. TestMapFile#testMainMethodMapFile creates test files in
hadoop-common project root. (Xiaoyu Yao via wheat9)
+ HADOOP-11467. KerberosAuthenticator can connect to a non-secure cluster.
+ (yzhangal via rkanter)
+
Release 2.6.1 - UNRELEASED
INCOMPATIBLE CHANGES