HDFS-4577. Webhdfs operations should declare if authentication is required. Contributed by Daryn Sharp.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1454517 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Kihwal Lee 2013-03-08 20:01:58 +00:00
parent a549d6fa2c
commit 140076fb57
8 changed files with 83 additions and 8 deletions

View File

@ -2384,6 +2384,9 @@ Release 0.23.7 - UNRELEASED
HDFS-4567. Webhdfs does not need a token for token operations (daryn via HDFS-4567. Webhdfs does not need a token for token operations (daryn via
kihwal) kihwal)
HDFS-4577. Webhdfs operations should declare if authentication is required
(daryn via kihwal)
Release 0.23.6 - UNRELEASED Release 0.23.6 - UNRELEASED
INCOMPATIBLE CHANGES INCOMPATIBLE CHANGES

View File

@ -344,10 +344,7 @@ Param<?,?>[] getAuthParameters(final HttpOpParam.Op op) throws IOException {
// Skip adding delegation token for token operations because these // Skip adding delegation token for token operations because these
// operations require authentication. // operations require authentication.
Token<?> token = null; Token<?> token = null;
if (UserGroupInformation.isSecurityEnabled() && if (UserGroupInformation.isSecurityEnabled() && !op.getRequireAuth()) {
op != GetOpParam.Op.GETDELEGATIONTOKEN &&
op != PutOpParam.Op.RENEWDELEGATIONTOKEN &&
op != PutOpParam.Op.CANCELDELEGATIONTOKEN) {
token = getDelegationToken(); token = getDelegationToken();
} }
if (token != null) { if (token != null) {

View File

@ -38,6 +38,11 @@ public HttpOpParam.Type getType() {
return HttpOpParam.Type.DELETE; return HttpOpParam.Type.DELETE;
} }
@Override
public boolean getRequireAuth() {
return false;
}
@Override @Override
public boolean getDoOutput() { public boolean getDoOutput() {
return false; return false;

View File

@ -31,7 +31,7 @@ public static enum Op implements HttpOpParam.Op {
GETFILECHECKSUM(true, HttpURLConnection.HTTP_OK), GETFILECHECKSUM(true, HttpURLConnection.HTTP_OK),
GETHOMEDIRECTORY(false, HttpURLConnection.HTTP_OK), GETHOMEDIRECTORY(false, HttpURLConnection.HTTP_OK),
GETDELEGATIONTOKEN(false, HttpURLConnection.HTTP_OK), GETDELEGATIONTOKEN(false, HttpURLConnection.HTTP_OK, true),
/** GET_BLOCK_LOCATIONS is a private unstable op. */ /** GET_BLOCK_LOCATIONS is a private unstable op. */
GET_BLOCK_LOCATIONS(false, HttpURLConnection.HTTP_OK), GET_BLOCK_LOCATIONS(false, HttpURLConnection.HTTP_OK),
@ -40,16 +40,28 @@ public static enum Op implements HttpOpParam.Op {
final boolean redirect; final boolean redirect;
final int expectedHttpResponseCode; final int expectedHttpResponseCode;
final boolean requireAuth;
Op(final boolean redirect, final int expectedHttpResponseCode) { Op(final boolean redirect, final int expectedHttpResponseCode) {
this(redirect, expectedHttpResponseCode, false);
}
Op(final boolean redirect, final int expectedHttpResponseCode,
final boolean requireAuth) {
this.redirect = redirect; this.redirect = redirect;
this.expectedHttpResponseCode = expectedHttpResponseCode; this.expectedHttpResponseCode = expectedHttpResponseCode;
this.requireAuth = requireAuth;
} }
@Override @Override
public HttpOpParam.Type getType() { public HttpOpParam.Type getType() {
return HttpOpParam.Type.GET; return HttpOpParam.Type.GET;
} }
@Override
public boolean getRequireAuth() {
return requireAuth;
}
@Override @Override
public boolean getDoOutput() { public boolean getDoOutput() {

View File

@ -43,6 +43,9 @@ public static interface Op {
/** @return the Http operation type. */ /** @return the Http operation type. */
public Type getType(); public Type getType();
/** @return true if the operation cannot use a token */
public boolean getRequireAuth();
/** @return true if the operation will do output. */ /** @return true if the operation will do output. */
public boolean getDoOutput(); public boolean getDoOutput();
@ -92,6 +95,11 @@ public Type getType() {
return op.getType(); return op.getType();
} }
@Override
public boolean getRequireAuth() {
return op.getRequireAuth();
}
@Override @Override
public boolean getDoOutput() { public boolean getDoOutput() {
return op.getDoOutput(); return op.getDoOutput();

View File

@ -41,6 +41,11 @@ public static enum Op implements HttpOpParam.Op {
public Type getType() { public Type getType() {
return Type.POST; return Type.POST;
} }
@Override
public boolean getRequireAuth() {
return false;
}
@Override @Override
public boolean getDoOutput() { public boolean getDoOutput() {

View File

@ -34,23 +34,35 @@ public static enum Op implements HttpOpParam.Op {
SETPERMISSION(false, HttpURLConnection.HTTP_OK), SETPERMISSION(false, HttpURLConnection.HTTP_OK),
SETTIMES(false, HttpURLConnection.HTTP_OK), SETTIMES(false, HttpURLConnection.HTTP_OK),
RENEWDELEGATIONTOKEN(false, HttpURLConnection.HTTP_OK), RENEWDELEGATIONTOKEN(false, HttpURLConnection.HTTP_OK, true),
CANCELDELEGATIONTOKEN(false, HttpURLConnection.HTTP_OK), CANCELDELEGATIONTOKEN(false, HttpURLConnection.HTTP_OK, true),
NULL(false, HttpURLConnection.HTTP_NOT_IMPLEMENTED); NULL(false, HttpURLConnection.HTTP_NOT_IMPLEMENTED);
final boolean doOutputAndRedirect; final boolean doOutputAndRedirect;
final int expectedHttpResponseCode; final int expectedHttpResponseCode;
final boolean requireAuth;
Op(final boolean doOutputAndRedirect, final int expectedHttpResponseCode) { Op(final boolean doOutputAndRedirect, final int expectedHttpResponseCode) {
this(doOutputAndRedirect, expectedHttpResponseCode, false);
}
Op(final boolean doOutputAndRedirect, final int expectedHttpResponseCode,
final boolean requireAuth) {
this.doOutputAndRedirect = doOutputAndRedirect; this.doOutputAndRedirect = doOutputAndRedirect;
this.expectedHttpResponseCode = expectedHttpResponseCode; this.expectedHttpResponseCode = expectedHttpResponseCode;
this.requireAuth = requireAuth;
} }
@Override @Override
public HttpOpParam.Type getType() { public HttpOpParam.Type getType() {
return HttpOpParam.Type.PUT; return HttpOpParam.Type.PUT;
} }
@Override
public boolean getRequireAuth() {
return requireAuth;
}
@Override @Override
public boolean getDoOutput() { public boolean getDoOutput() {

View File

@ -28,8 +28,10 @@
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier; import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier;
import org.apache.hadoop.hdfs.web.resources.DeleteOpParam;
import org.apache.hadoop.hdfs.web.resources.GetOpParam; import org.apache.hadoop.hdfs.web.resources.GetOpParam;
import org.apache.hadoop.hdfs.web.resources.HttpOpParam; import org.apache.hadoop.hdfs.web.resources.HttpOpParam;
import org.apache.hadoop.hdfs.web.resources.PostOpParam;
import org.apache.hadoop.hdfs.web.resources.PutOpParam; import org.apache.hadoop.hdfs.web.resources.PutOpParam;
import org.apache.hadoop.security.SecurityUtil; import org.apache.hadoop.security.SecurityUtil;
import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.UserGroupInformation;
@ -166,4 +168,35 @@ private void checkNoTokenForOperation(HttpOpParam.Op op) throws IOException {
verify(fs, never()).setDelegationToken(any(Token.class)); verify(fs, never()).setDelegationToken(any(Token.class));
verify(fs, never()).addRenewAction(fs); verify(fs, never()).addRenewAction(fs);
} }
}
@Test(timeout=1000)
public void testGetOpRequireAuth() {
for (HttpOpParam.Op op : GetOpParam.Op.values()) {
boolean expect = (op == GetOpParam.Op.GETDELEGATIONTOKEN);
assertEquals(expect, op.getRequireAuth());
}
}
@Test(timeout=1000)
public void testPutOpRequireAuth() {
for (HttpOpParam.Op op : PutOpParam.Op.values()) {
boolean expect = (op == PutOpParam.Op.RENEWDELEGATIONTOKEN ||
op == PutOpParam.Op.CANCELDELEGATIONTOKEN);
assertEquals(expect, op.getRequireAuth());
}
}
@Test(timeout=1000)
public void testPostOpRequireAuth() {
for (HttpOpParam.Op op : PostOpParam.Op.values()) {
assertFalse(op.getRequireAuth());
}
}
@Test(timeout=1000)
public void testDeleteOpRequireAuth() {
for (HttpOpParam.Op op : DeleteOpParam.Op.values()) {
assertFalse(op.getRequireAuth());
}
}
}