HDFS-4564. Ensure webhdfs returns correct HTTP response codes for denied operations. Contributed by Daryn Sharp.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1583241 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3532d96ff6
commit
004d0854b7
@ -349,7 +349,7 @@ public void testDelegationTokenOperations() throws Exception {
|
||||
url = new URL(TestJettyHelper.getJettyURL(),
|
||||
"/webhdfs/v1/?op=GETHOMEDIRECTORY&delegation=" + tokenStr);
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
Assert.assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED,
|
||||
Assert.assertEquals(HttpURLConnection.HTTP_FORBIDDEN,
|
||||
conn.getResponseCode());
|
||||
}
|
||||
|
||||
|
@ -1050,6 +1050,9 @@ BREAKDOWN OF HDFS-5535 ROLLING UPGRADE SUBTASKS AND RELATED JIRAS
|
||||
HDFS-6038. Allow JournalNode to handle editlog produced by new release with
|
||||
future layoutversion. (jing9)
|
||||
|
||||
HDFS-4564. Ensure webhdfs returns correct HTTP response codes for denied
|
||||
operations. (daryn via acmurthy)
|
||||
|
||||
Release 2.3.1 - UNRELEASED
|
||||
|
||||
INCOMPATIBLE CHANGES
|
||||
|
@ -304,6 +304,11 @@ private Path makeAbsolute(Path f) {
|
||||
private static Map<?, ?> validateResponse(final HttpOpParam.Op op,
|
||||
final HttpURLConnection conn, boolean unwrapException) throws IOException {
|
||||
final int code = conn.getResponseCode();
|
||||
// server is demanding an authentication we don't support
|
||||
if (code == HttpURLConnection.HTTP_UNAUTHORIZED) {
|
||||
throw new IOException(
|
||||
new AuthenticationException(conn.getResponseMessage()));
|
||||
}
|
||||
if (code != op.getExpectedHttpResponseCode()) {
|
||||
final Map<?, ?> m;
|
||||
try {
|
||||
@ -450,52 +455,33 @@ protected AbstractRunner(final HttpOpParam.Op op, boolean redirected) {
|
||||
this.redirected = redirected;
|
||||
}
|
||||
|
||||
private HttpURLConnection getHttpUrlConnection(final URL url)
|
||||
throws IOException, AuthenticationException {
|
||||
AbstractRunner run() throws IOException {
|
||||
UserGroupInformation connectUgi = ugi.getRealUser();
|
||||
if (connectUgi == null) {
|
||||
connectUgi = ugi;
|
||||
}
|
||||
if (op.getRequireAuth()) {
|
||||
connectUgi.checkTGTAndReloginFromKeytab();
|
||||
}
|
||||
try {
|
||||
// the entire lifecycle of the connection must be run inside the
|
||||
// doAs to ensure authentication is performed correctly
|
||||
return connectUgi.doAs(
|
||||
new PrivilegedExceptionAction<HttpURLConnection>() {
|
||||
new PrivilegedExceptionAction<AbstractRunner>() {
|
||||
@Override
|
||||
public HttpURLConnection run() throws IOException {
|
||||
return openHttpUrlConnection(url);
|
||||
public AbstractRunner run() throws IOException {
|
||||
return runWithRetry();
|
||||
}
|
||||
});
|
||||
} catch (IOException ioe) {
|
||||
Throwable cause = ioe.getCause();
|
||||
if (cause != null && cause instanceof AuthenticationException) {
|
||||
throw (AuthenticationException)cause;
|
||||
}
|
||||
throw ioe;
|
||||
} catch (InterruptedException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private HttpURLConnection openHttpUrlConnection(final URL url)
|
||||
throws IOException {
|
||||
final HttpURLConnection conn;
|
||||
try {
|
||||
conn = (HttpURLConnection) connectionFactory.openConnection(url,
|
||||
op.getRequireAuth());
|
||||
} catch (AuthenticationException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
|
||||
private void init() throws IOException {
|
||||
checkRetry = !redirected;
|
||||
URL url = getUrl();
|
||||
try {
|
||||
conn = getHttpUrlConnection(url);
|
||||
} catch(AuthenticationException ae) {
|
||||
checkRetry = false;
|
||||
throw new IOException("Authentication failed, url=" + url, ae);
|
||||
}
|
||||
conn = (HttpURLConnection) connectionFactory.openConnection(url);
|
||||
}
|
||||
|
||||
private void connect() throws IOException {
|
||||
@ -516,7 +502,7 @@ private void disconnect() {
|
||||
}
|
||||
}
|
||||
|
||||
AbstractRunner run() throws IOException {
|
||||
private AbstractRunner runWithRetry() throws IOException {
|
||||
/**
|
||||
* Do the real work.
|
||||
*
|
||||
@ -543,6 +529,10 @@ AbstractRunner run() throws IOException {
|
||||
}
|
||||
return this;
|
||||
} catch(IOException ioe) {
|
||||
Throwable cause = ioe.getCause();
|
||||
if (cause != null && cause instanceof AuthenticationException) {
|
||||
throw ioe; // no retries for auth failures
|
||||
}
|
||||
shouldRetry(ioe, retry);
|
||||
}
|
||||
}
|
||||
|
@ -77,9 +77,9 @@ public Response toResponse(Exception e) {
|
||||
//Map response status
|
||||
final Response.Status s;
|
||||
if (e instanceof SecurityException) {
|
||||
s = Response.Status.UNAUTHORIZED;
|
||||
s = Response.Status.FORBIDDEN;
|
||||
} else if (e instanceof AuthorizationException) {
|
||||
s = Response.Status.UNAUTHORIZED;
|
||||
s = Response.Status.FORBIDDEN;
|
||||
} else if (e instanceof FileNotFoundException) {
|
||||
s = Response.Status.NOT_FOUND;
|
||||
} else if (e instanceof IOException) {
|
||||
|
@ -410,7 +410,7 @@ public void testResponseCode() throws IOException {
|
||||
new DoAsParam(ugi.getShortUserName() + "proxy"));
|
||||
final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.connect();
|
||||
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, conn.getResponseCode());
|
||||
assertEquals(HttpServletResponse.SC_FORBIDDEN, conn.getResponseCode());
|
||||
conn.disconnect();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user