HADOOP-8465. hadoop-auth should support ephemeral authentication (tucu)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1349613 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Alejandro Abdelnur 2012-06-13 02:22:06 +00:00
parent 0297662ffe
commit 5a2e0ee4d2
4 changed files with 52 additions and 32 deletions

View File

@ -347,7 +347,8 @@ public class AuthenticationFilter implements Filter {
LOG.debug("Request [{}] triggering authentication", getRequestURL(httpRequest)); LOG.debug("Request [{}] triggering authentication", getRequestURL(httpRequest));
} }
token = authHandler.authenticate(httpRequest, httpResponse); token = authHandler.authenticate(httpRequest, httpResponse);
if (token != null && token != AuthenticationToken.ANONYMOUS) { if (token != null && token.getExpires() != 0 &&
token != AuthenticationToken.ANONYMOUS) {
token.setExpires(System.currentTimeMillis() + getValidity() * 1000); token.setExpires(System.currentTimeMillis() + getValidity() * 1000);
} }
newToken = true; newToken = true;
@ -375,7 +376,7 @@ public class AuthenticationFilter implements Filter {
return (authToken != AuthenticationToken.ANONYMOUS) ? authToken : null; return (authToken != AuthenticationToken.ANONYMOUS) ? authToken : null;
} }
}; };
if (newToken && token != AuthenticationToken.ANONYMOUS) { if (newToken && !token.isExpired() && token != AuthenticationToken.ANONYMOUS) {
String signedToken = signer.sign(token.toString()); String signedToken = signer.sign(token.toString());
Cookie cookie = createCookie(signedToken); Cookie cookie = createCookie(signedToken);
httpResponse.addCookie(cookie); httpResponse.addCookie(cookie);

View File

@ -115,10 +115,10 @@ public class AuthenticationToken implements Principal {
*/ */
private void generateToken() { private void generateToken() {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
sb.append(USER_NAME).append("=").append(userName).append(ATTR_SEPARATOR); sb.append(USER_NAME).append("=").append(getUserName()).append(ATTR_SEPARATOR);
sb.append(PRINCIPAL).append("=").append(principal).append(ATTR_SEPARATOR); sb.append(PRINCIPAL).append("=").append(getName()).append(ATTR_SEPARATOR);
sb.append(TYPE).append("=").append(type).append(ATTR_SEPARATOR); sb.append(TYPE).append("=").append(getType()).append(ATTR_SEPARATOR);
sb.append(EXPIRES).append("=").append(expires); sb.append(EXPIRES).append("=").append(getExpires());
token = sb.toString(); token = sb.toString();
} }
@ -165,7 +165,7 @@ public class AuthenticationToken implements Principal {
* @return if the token has expired. * @return if the token has expired.
*/ */
public boolean isExpired() { public boolean isExpired() {
return expires != -1 && System.currentTimeMillis() > expires; return getExpires() != -1 && System.currentTimeMillis() > getExpires();
} }
/** /**

View File

@ -73,6 +73,7 @@ public class TestAuthenticationFilter extends TestCase {
public static boolean init; public static boolean init;
public static boolean managementOperationReturn; public static boolean managementOperationReturn;
public static boolean destroy; public static boolean destroy;
public static boolean expired;
public static final String TYPE = "dummy"; public static final String TYPE = "dummy";
@ -86,6 +87,7 @@ public class TestAuthenticationFilter extends TestCase {
init = true; init = true;
managementOperationReturn = managementOperationReturn =
config.getProperty("management.operation.return", "true").equals("true"); config.getProperty("management.operation.return", "true").equals("true");
expired = config.getProperty("expired.token", "false").equals("true");
} }
@Override @Override
@ -116,7 +118,7 @@ public class TestAuthenticationFilter extends TestCase {
String param = request.getParameter("authenticated"); String param = request.getParameter("authenticated");
if (param != null && param.equals("true")) { if (param != null && param.equals("true")) {
token = new AuthenticationToken("u", "p", "t"); token = new AuthenticationToken("u", "p", "t");
token.setExpires(System.currentTimeMillis() + 1000); token.setExpires((expired) ? 0 : System.currentTimeMillis() + 1000);
} else { } else {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
} }
@ -386,12 +388,16 @@ public class TestAuthenticationFilter extends TestCase {
} }
} }
private void _testDoFilterAuthentication(boolean withDomainPath, boolean invalidToken) throws Exception { private void _testDoFilterAuthentication(boolean withDomainPath,
boolean invalidToken,
boolean expired) throws Exception {
AuthenticationFilter filter = new AuthenticationFilter(); AuthenticationFilter filter = new AuthenticationFilter();
try { try {
FilterConfig config = Mockito.mock(FilterConfig.class); FilterConfig config = Mockito.mock(FilterConfig.class);
Mockito.when(config.getInitParameter("management.operation.return")). Mockito.when(config.getInitParameter("management.operation.return")).
thenReturn("true"); thenReturn("true");
Mockito.when(config.getInitParameter("expired.token")).
thenReturn(Boolean.toString(expired));
Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn( Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn(
DummyAuthenticationHandler.class.getName()); DummyAuthenticationHandler.class.getName());
Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TOKEN_VALIDITY)).thenReturn("1000"); Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TOKEN_VALIDITY)).thenReturn("1000");
@ -400,7 +406,8 @@ public class TestAuthenticationFilter extends TestCase {
new Vector<String>(Arrays.asList(AuthenticationFilter.AUTH_TYPE, new Vector<String>(Arrays.asList(AuthenticationFilter.AUTH_TYPE,
AuthenticationFilter.AUTH_TOKEN_VALIDITY, AuthenticationFilter.AUTH_TOKEN_VALIDITY,
AuthenticationFilter.SIGNATURE_SECRET, AuthenticationFilter.SIGNATURE_SECRET,
"management.operation.return")).elements()); "management.operation.return",
"expired.token")).elements());
if (withDomainPath) { if (withDomainPath) {
Mockito.when(config.getInitParameter(AuthenticationFilter.COOKIE_DOMAIN)).thenReturn(".foo.com"); Mockito.when(config.getInitParameter(AuthenticationFilter.COOKIE_DOMAIN)).thenReturn(".foo.com");
@ -457,26 +464,32 @@ public class TestAuthenticationFilter extends TestCase {
filter.doFilter(request, response, chain); filter.doFilter(request, response, chain);
assertNotNull(setCookie[0]); if (expired) {
assertEquals(AuthenticatedURL.AUTH_COOKIE, setCookie[0].getName()); Mockito.verify(response, Mockito.never()).
assertTrue(setCookie[0].getValue().contains("u=")); addCookie(Mockito.any(Cookie.class));
assertTrue(setCookie[0].getValue().contains("p="));
assertTrue(setCookie[0].getValue().contains("t="));
assertTrue(setCookie[0].getValue().contains("e="));
assertTrue(setCookie[0].getValue().contains("s="));
assertTrue(calledDoFilter[0]);
Signer signer = new Signer("secret".getBytes());
String value = signer.verifyAndExtract(setCookie[0].getValue());
AuthenticationToken token = AuthenticationToken.parse(value);
assertEquals(System.currentTimeMillis() + 1000 * 1000, token.getExpires(), 100);
if (withDomainPath) {
assertEquals(".foo.com", setCookie[0].getDomain());
assertEquals("/bar", setCookie[0].getPath());
} else { } else {
assertNull(setCookie[0].getDomain()); assertNotNull(setCookie[0]);
assertNull(setCookie[0].getPath()); assertEquals(AuthenticatedURL.AUTH_COOKIE, setCookie[0].getName());
assertTrue(setCookie[0].getValue().contains("u="));
assertTrue(setCookie[0].getValue().contains("p="));
assertTrue(setCookie[0].getValue().contains("t="));
assertTrue(setCookie[0].getValue().contains("e="));
assertTrue(setCookie[0].getValue().contains("s="));
assertTrue(calledDoFilter[0]);
Signer signer = new Signer("secret".getBytes());
String value = signer.verifyAndExtract(setCookie[0].getValue());
AuthenticationToken token = AuthenticationToken.parse(value);
assertEquals(System.currentTimeMillis() + 1000 * 1000,
token.getExpires(), 100);
if (withDomainPath) {
assertEquals(".foo.com", setCookie[0].getDomain());
assertEquals("/bar", setCookie[0].getPath());
} else {
assertNull(setCookie[0].getDomain());
assertNull(setCookie[0].getPath());
}
} }
} finally { } finally {
filter.destroy(); filter.destroy();
@ -484,15 +497,19 @@ public class TestAuthenticationFilter extends TestCase {
} }
public void testDoFilterAuthentication() throws Exception { public void testDoFilterAuthentication() throws Exception {
_testDoFilterAuthentication(false, false); _testDoFilterAuthentication(false, false, false);
}
public void testDoFilterAuthenticationImmediateExpiration() throws Exception {
_testDoFilterAuthentication(false, false, true);
} }
public void testDoFilterAuthenticationWithInvalidToken() throws Exception { public void testDoFilterAuthenticationWithInvalidToken() throws Exception {
_testDoFilterAuthentication(false, true); _testDoFilterAuthentication(false, true, false);
} }
public void testDoFilterAuthenticationWithDomainPath() throws Exception { public void testDoFilterAuthenticationWithDomainPath() throws Exception {
_testDoFilterAuthentication(true, false); _testDoFilterAuthentication(true, false, false);
} }
public void testDoFilterAuthenticated() throws Exception { public void testDoFilterAuthenticated() throws Exception {

View File

@ -177,6 +177,8 @@ Branch-2 ( Unreleased changes )
HADOOP-8458. Add management hook to AuthenticationHandler to enable HADOOP-8458. Add management hook to AuthenticationHandler to enable
delegation token operations support (tucu) delegation token operations support (tucu)
HADOOP-8465. hadoop-auth should support ephemeral authentication (tucu)
IMPROVEMENTS IMPROVEMENTS
HADOOP-8340. SNAPSHOT build versions should compare as less than their eventual HADOOP-8340. SNAPSHOT build versions should compare as less than their eventual