diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/AuthenticationWithProxyUserFilter.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/AuthenticationWithProxyUserFilter.java
index c97f8ad8144..ea9b282ab89 100644
--- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/AuthenticationWithProxyUserFilter.java
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/AuthenticationWithProxyUserFilter.java
@@ -20,10 +20,9 @@ package org.apache.hadoop.security;
import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
import org.apache.hadoop.security.authorize.AuthorizationException;
import org.apache.hadoop.security.authorize.ProxyUsers;
+import org.apache.hadoop.util.HttpExceptionUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
@@ -42,9 +41,6 @@ import java.util.List;
*/
public class AuthenticationWithProxyUserFilter extends AuthenticationFilter {
- public static final Logger LOG =
- LoggerFactory.getLogger(AuthenticationWithProxyUserFilter.class);
-
/**
* Constant used in URL's query string to perform a proxy user request, the
* value of the DO_AS
parameter is the user the request will be
@@ -70,30 +66,29 @@ public class AuthenticationWithProxyUserFilter extends AuthenticationFilter {
protected void doFilter(FilterChain filterChain, HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
- final String proxyUser = getDoAs(request);
+ // authorize proxy user before calling next filter.
+ String proxyUser = getDoAs(request);
if (proxyUser != null) {
+ UserGroupInformation realUser =
+ UserGroupInformation.createRemoteUser(request.getRemoteUser());
+ UserGroupInformation proxyUserInfo =
+ UserGroupInformation.createProxyUser(proxyUser, realUser);
+ try {
+ ProxyUsers.authorize(proxyUserInfo, request.getRemoteAddr());
+ } catch (AuthorizationException ex) {
+ HttpExceptionUtils.createServletExceptionResponse(response,
+ HttpServletResponse.SC_FORBIDDEN, ex);
+ // stop filter chain if there is an Authorization Exception.
+ return;
+ }
+
+ final UserGroupInformation finalProxyUser = proxyUserInfo;
// Change the remote user after proxy user is authorized.
- final HttpServletRequest finalReq = request;
- request = new HttpServletRequestWrapper(finalReq) {
-
- private String getRemoteOrProxyUser() throws AuthorizationException {
- UserGroupInformation realUser =
- UserGroupInformation.createRemoteUser(finalReq.getRemoteUser());
- UserGroupInformation proxyUserInfo =
- UserGroupInformation.createProxyUser(proxyUser, realUser);
- ProxyUsers.authorize(proxyUserInfo, finalReq.getRemoteAddr());
- return proxyUserInfo.getUserName();
- }
-
+ request = new HttpServletRequestWrapper(request) {
@Override
public String getRemoteUser() {
- try {
- return getRemoteOrProxyUser();
- } catch (AuthorizationException ex) {
- LOG.error("Unable to verify proxy user: " + ex.getMessage(), ex);
- }
- return null;
+ return finalProxyUser.getUserName();
}
};
diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServerWithSpengo.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServerWithSpengo.java
index e1d7302c9a2..95c5ecc81e5 100644
--- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServerWithSpengo.java
+++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServerWithSpengo.java
@@ -178,25 +178,12 @@ public class TestHttpServerWithSpengo {
Assert.assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode());
}
- // userA cannot impersonate userC, but for /stacks, /jmx and /conf,
- // they doesn't require users to authorize by default, so they
- // can be accessed.
+ // userA cannot impersonate userC, it fails.
for (String servlet :
new String[]{"stacks", "jmx", "conf"}){
HttpURLConnection conn = authUrl
.openConnection(new URL(serverURL + servlet + "?doAs=userC"),
token);
- Assert.assertEquals(HttpURLConnection.HTTP_OK,
- conn.getResponseCode());
- }
-
- // "/logs" and "/logLevel" require admin authorization,
- // only userA has the access.
- for (String servlet :
- new String[]{"logLevel", "logs"}) {
- HttpURLConnection conn = authUrl
- .openConnection(new URL(serverURL + servlet + "?doAs=userC"),
- token);
Assert.assertEquals(HttpURLConnection.HTTP_FORBIDDEN,
conn.getResponseCode());
}
diff --git a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AppController.java b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AppController.java
index 1ba37c9ca87..ad5bc2a430f 100644
--- a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AppController.java
+++ b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AppController.java
@@ -393,11 +393,10 @@ public class AppController extends Controller implements AMParams {
*/
boolean checkAccess(Job job) {
String remoteUser = request().getRemoteUser();
- if (remoteUser == null) {
- return false;
+ UserGroupInformation callerUGI = null;
+ if (remoteUser != null) {
+ callerUGI = UserGroupInformation.createRemoteUser(remoteUser);
}
- UserGroupInformation callerUGI =
- UserGroupInformation.createRemoteUser(remoteUser);
if (callerUGI != null && !job.checkAccess(callerUGI, JobACL.VIEW_JOB)) {
return false;
}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppBlock.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppBlock.java
index a8810a9ec8c..4a47bf181c2 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppBlock.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppBlock.java
@@ -32,7 +32,6 @@ import org.apache.commons.lang.StringEscapeUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.CommonConfigurationKeys;
import org.apache.hadoop.security.UserGroupInformation;
-import org.apache.hadoop.security.authentication.client.AuthenticationException;
import org.apache.hadoop.security.http.RestCsrfPreventionFilter;
import org.apache.hadoop.util.StringUtils;
import org.apache.hadoop.yarn.api.ApplicationBaseProtocol;
@@ -110,8 +109,8 @@ public class AppBlock extends HtmlBlock {
final GetApplicationReportRequest request =
GetApplicationReportRequest.newInstance(appID);
if (callerUGI == null) {
- throw new AuthenticationException(
- "Failed to get user name from request");
+ appReport =
+ appBaseProt.getApplicationReport(request).getApplicationReport();
} else {
appReport = callerUGI.doAs(
new PrivilegedExceptionAction () {
@@ -205,55 +204,36 @@ public class AppBlock extends HtmlBlock {
String schedulerPath = WebAppUtils.getResolvedRMWebAppURLWithScheme(conf) +
"/cluster/scheduler?openQueues=" + app.getQueue();
- generateOverviewTable(app, schedulerPath, webUiType, appReport);
-
- createApplicationMetricsTable(html);
-
- html.__(InfoBlock.class);
-
- generateApplicationTable(html, callerUGI, attempts);
-
- }
-
- /**
- * Generate overview table for app web page.
- * @param app app info.
- * @param schedulerPath schedule path.
- * @param webUiType web ui type.
- * @param appReport app report.
- */
- private void generateOverviewTable(AppInfo app, String schedulerPath,
- String webUiType, ApplicationReport appReport) {
ResponseInfo overviewTable = info("Application Overview")
- .__("User:", schedulerPath, app.getUser())
- .__("Name:", app.getName())
- .__("Application Type:", app.getType())
- .__("Application Tags:",
- app.getApplicationTags() == null ? "" : app.getApplicationTags())
- .__("Application Priority:", clarifyAppPriority(app.getPriority()))
- .__(
- "YarnApplicationState:",
- app.getAppState() == null ? UNAVAILABLE : clarifyAppState(app
- .getAppState()))
- .__("Queue:", schedulerPath, app.getQueue())
- .__("FinalStatus Reported by AM:",
- clairfyAppFinalStatus(app.getFinalAppStatus()))
- .__("Started:", Times.format(app.getStartedTime()))
- .__(
- "Elapsed:",
- StringUtils.formatTime(Times.elapsed(app.getStartedTime(),
- app.getFinishedTime())))
- .__(
- "Tracking URL:",
- app.getTrackingUrl() == null
- || app.getTrackingUrl().equals(UNAVAILABLE) ? null : root_url(app
- .getTrackingUrl()),
- app.getTrackingUrl() == null
- || app.getTrackingUrl().equals(UNAVAILABLE) ? "Unassigned" : app
- .getAppState() == YarnApplicationState.FINISHED
- || app.getAppState() == YarnApplicationState.FAILED
- || app.getAppState() == YarnApplicationState.KILLED ? "History"
- : "ApplicationMaster");
+ .__("User:", schedulerPath, app.getUser())
+ .__("Name:", app.getName())
+ .__("Application Type:", app.getType())
+ .__("Application Tags:",
+ app.getApplicationTags() == null ? "" : app.getApplicationTags())
+ .__("Application Priority:", clarifyAppPriority(app.getPriority()))
+ .__(
+ "YarnApplicationState:",
+ app.getAppState() == null ? UNAVAILABLE : clarifyAppState(app
+ .getAppState()))
+ .__("Queue:", schedulerPath, app.getQueue())
+ .__("FinalStatus Reported by AM:",
+ clairfyAppFinalStatus(app.getFinalAppStatus()))
+ .__("Started:", Times.format(app.getStartedTime()))
+ .__(
+ "Elapsed:",
+ StringUtils.formatTime(Times.elapsed(app.getStartedTime(),
+ app.getFinishedTime())))
+ .__(
+ "Tracking URL:",
+ app.getTrackingUrl() == null
+ || app.getTrackingUrl().equals(UNAVAILABLE) ? null : root_url(app
+ .getTrackingUrl()),
+ app.getTrackingUrl() == null
+ || app.getTrackingUrl().equals(UNAVAILABLE) ? "Unassigned" : app
+ .getAppState() == YarnApplicationState.FINISHED
+ || app.getAppState() == YarnApplicationState.FAILED
+ || app.getAppState() == YarnApplicationState.KILLED ? "History"
+ : "ApplicationMaster");
if (webUiType != null
&& webUiType.equals(YarnWebParams.RM_WEB_UI)) {
LogAggregationStatus status = getLogAggregationStatus();
@@ -285,6 +265,37 @@ public class AppBlock extends HtmlBlock {
overviewTable.__("AM container Node Label expression:",
app.getAmNodeLabelExpression() == null ? ""
: app.getAmNodeLabelExpression());
+
+ try {
+ final GetApplicationAttemptsRequest request =
+ GetApplicationAttemptsRequest.newInstance(appID);
+ if (callerUGI == null) {
+ attempts = appBaseProt.getApplicationAttempts(request)
+ .getApplicationAttemptList();
+ } else {
+ attempts = callerUGI.doAs(
+ new PrivilegedExceptionAction> () {
+ @Override
+ public Collection run() throws Exception {
+ return appBaseProt.getApplicationAttempts(request)
+ .getApplicationAttemptList();
+ }
+ });
+ }
+ } catch (Exception e) {
+ String message =
+ "Failed to read the attempts of the application " + appID + ".";
+ LOG.error(message, e);
+ html.p().__(message).__();
+ return;
+ }
+
+ createApplicationMetricsTable(html);
+
+ html.__(InfoBlock.class);
+
+ generateApplicationTable(html, callerUGI, attempts);
+
}
protected void generateApplicationTable(Block html,