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 void doFilter(ServletRequest request, ServletResponse response, FilterCha
LOG.debug("Request [{}] triggering authentication", getRequestURL(httpRequest));
}
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);
}
newToken = true;
@ -375,7 +376,7 @@ public Principal getUserPrincipal() {
return (authToken != AuthenticationToken.ANONYMOUS) ? authToken : null;
}
};
if (newToken && token != AuthenticationToken.ANONYMOUS) {
if (newToken && !token.isExpired() && token != AuthenticationToken.ANONYMOUS) {
String signedToken = signer.sign(token.toString());
Cookie cookie = createCookie(signedToken);
httpResponse.addCookie(cookie);

View File

@ -115,10 +115,10 @@ public void setExpires(long expires) {
*/
private void generateToken() {
StringBuffer sb = new StringBuffer();
sb.append(USER_NAME).append("=").append(userName).append(ATTR_SEPARATOR);
sb.append(PRINCIPAL).append("=").append(principal).append(ATTR_SEPARATOR);
sb.append(TYPE).append("=").append(type).append(ATTR_SEPARATOR);
sb.append(EXPIRES).append("=").append(expires);
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();
}
@ -165,7 +165,7 @@ public long getExpires() {
* @return if the token has expired.
*/
public boolean isExpired() {
return expires != -1 && System.currentTimeMillis() > expires;
return getExpires() != -1 && System.currentTimeMillis() > getExpires();
}
/**

View File

@ -73,6 +73,7 @@ public static class DummyAuthenticationHandler implements AuthenticationHandler
public static boolean init;
public static boolean managementOperationReturn;
public static boolean destroy;
public static boolean expired;
public static final String TYPE = "dummy";
@ -86,6 +87,7 @@ public void init(Properties config) throws ServletException {
init = true;
managementOperationReturn =
config.getProperty("management.operation.return", "true").equals("true");
expired = config.getProperty("expired.token", "false").equals("true");
}
@Override
@ -116,7 +118,7 @@ public AuthenticationToken authenticate(HttpServletRequest request, HttpServletR
String param = request.getParameter("authenticated");
if (param != null && param.equals("true")) {
token = new AuthenticationToken("u", "p", "t");
token.setExpires(System.currentTimeMillis() + 1000);
token.setExpires((expired) ? 0 : System.currentTimeMillis() + 1000);
} else {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
@ -386,12 +388,16 @@ public Object answer(InvocationOnMock invocation) throws Throwable {
}
}
private void _testDoFilterAuthentication(boolean withDomainPath, boolean invalidToken) throws Exception {
private void _testDoFilterAuthentication(boolean withDomainPath,
boolean invalidToken,
boolean expired) throws Exception {
AuthenticationFilter filter = new AuthenticationFilter();
try {
FilterConfig config = Mockito.mock(FilterConfig.class);
Mockito.when(config.getInitParameter("management.operation.return")).
thenReturn("true");
Mockito.when(config.getInitParameter("expired.token")).
thenReturn(Boolean.toString(expired));
Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn(
DummyAuthenticationHandler.class.getName());
Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TOKEN_VALIDITY)).thenReturn("1000");
@ -400,7 +406,8 @@ private void _testDoFilterAuthentication(boolean withDomainPath, boolean invalid
new Vector<String>(Arrays.asList(AuthenticationFilter.AUTH_TYPE,
AuthenticationFilter.AUTH_TOKEN_VALIDITY,
AuthenticationFilter.SIGNATURE_SECRET,
"management.operation.return")).elements());
"management.operation.return",
"expired.token")).elements());
if (withDomainPath) {
Mockito.when(config.getInitParameter(AuthenticationFilter.COOKIE_DOMAIN)).thenReturn(".foo.com");
@ -457,26 +464,32 @@ public Object answer(InvocationOnMock invocation) throws Throwable {
filter.doFilter(request, response, chain);
assertNotNull(setCookie[0]);
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());
if (expired) {
Mockito.verify(response, Mockito.never()).
addCookie(Mockito.any(Cookie.class));
} else {
assertNull(setCookie[0].getDomain());
assertNull(setCookie[0].getPath());
assertNotNull(setCookie[0]);
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 {
filter.destroy();
@ -484,15 +497,19 @@ public Object answer(InvocationOnMock invocation) throws Throwable {
}
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 {
_testDoFilterAuthentication(false, true);
_testDoFilterAuthentication(false, true, false);
}
public void testDoFilterAuthenticationWithDomainPath() throws Exception {
_testDoFilterAuthentication(true, false);
_testDoFilterAuthentication(true, false, false);
}
public void testDoFilterAuthenticated() throws Exception {

View File

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