开启 kerberos 后,HiveServer2 的 webui 没有内容。页面如下,可以打开,但是即便已经有会话,也有SQL执行,这里一直这样。
1. 原因分析
1.1 hiveserver2.jsp
以Active Sessions 的内容为例,./service/src/resources/hive-webapps/hiveserver2/hiveserver2.jsp 的内容如下:
<%
Collection<HiveSession> hiveSessions = sessionManager.getSessions();
int sessionCount = 0;
for (HiveSession hiveSession: hiveSessions) {
// Permission check
if (!HttpServer.hasAccess(remoteUser, hiveSession.getUserName(), ctx, request)) {
continue;
}
sessionCount++;
%>
<tr>
<td><%= hiveSession.getUserName() %></td>
<td><%= hiveSession.getIpAddress() %></td>
<td><%= hiveSession.getOpenOperationCount() %></td>
<td><%= (currentTime - hiveSession.getCreationTime())/1000 %></td>
<td><%= (currentTime - hiveSession.getLastAccessTime())/1000 %></td>
</tr>
<%
}
%>
从 sessionManager 获取了所有的 session,每个 session 进行判断 HttpServer.hasAccess
是否为true,如果为 true 则输出一行。
1.2 hasAccess 的代码如下:
先判断是否相等,remoteUser 是浏览器传递的用户,如果浏览器所在的电脑安装并配置 kerberos-client,则能正确的传递用户,否则是 null。
参考文档:
Activating the Hive Web UI
Windows 系统的配置链接
public static boolean hasAccess(String remoteUser, String user,
ServletContext ctx, HttpServletRequest request) throws IOException {
return StringUtils.equalsIgnoreCase(remoteUser, user) ||
HttpServer.hasAdministratorAccess(ctx, request, null);
}
1.3 hasAdministratorAccess 代码如下:
如果参数 CommonConfigurationKeys.HADOOP_SECURITY_AUTHORIZATION = false,则直接返回 true。否则进行用户判断。
static boolean hasAdministratorAccess(
ServletContext servletContext, HttpServletRequest request,
HttpServletResponse response) throws IOException {
Configuration conf =
(Configuration) servletContext.getAttribute(CONF_CONTEXT_ATTRIBUTE);
// If there is no authorization, anybody has administrator access.
if (!conf.getBoolean(
CommonConfigurationKeys.HADOOP_SECURITY_AUTHORIZATION, false)) {
return true;
}
String remoteUser = request.getRemoteUser();
if (remoteUser == null) {
if (response != null) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
"Unauthenticated users are not " +
"authorized to access this page.");
}
return false;
}
if (servletContext.getAttribute(ADMINS_ACL) != null &&
!userHasAdministratorAccess(servletContext, remoteUser)) {
if (response != null) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "User "
+ remoteUser + " is unauthorized to access this page.");
}
return false;
}
return true;
}
2. 解决方案
2.1 hiveserver2-site.xml 配置
hiveserver2-site.xml 配置 hadoop.security.authorization=false
。
不能改 core-site.xml, 因为 core-site.xml 的配置影响所有的组件。而 hiveserver2-site.xml 仅影响 hiveserver2,并且 hive
authorization 由参数 hive.security.authorization.enabled
控制。