[
https://issues.apache.org/jira/browse/HBASE-20472?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Nihal Jain updated HBASE-20472:
-------------------------------
Description:
The adminsAcl property can be used to restrict access to certain sections of
the web UI only to a particular set of users/groups. But in hbase, adminAcl
variable for InfoServer is always null, rendering it to not honour any acl set
by the admin. In fact I could not find any property in hbase to specify acl
list for web server.
*Analysis*:
* *InfoSever* object forgets(?) to set any *adminAcl* in the builder object
for http server.
{code:java}
public InfoServer(String name, String bindAddress, int port, boolean findPort,
final Configuration c) {
.
.
HttpServer.Builder builder =
new org.apache.hadoop.hbase.http.HttpServer.Builder();
.
.
this.httpServer = builder.build();
}{code}
[See InfoServer
constructor|https://github.com/apache/hbase/blob/46cb5dfa226892fd2580f26ce9ce77225bd7e67c/hbase-http/src/main/java/org/apache/hadoop/hbase/http/InfoServer.java#L55]
* http server retreives a null value and sets it as adminsAcl, which is passed
to *createWebAppContext*() method
{code:java}
private HttpServer(final Builder b) throws IOException {
.
.
.
this.adminsAcl = b.adminsAcl;
this.webAppContext = createWebAppContext(b.name, b.conf, adminsAcl, appDir);
.
.
}{code}
[See L527
HttpServer.java|https://github.com/apache/hbase/blob/46cb5dfa226892fd2580f26ce9ce77225bd7e67c/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java#L527]
* This method next sets *ADMIN_ACL* attribute for the servlet context to *null*
{code:java}
private static WebAppContext createWebAppContext(String name,
Configuration conf, AccessControlList adminsAcl, final String appDir) {
WebAppContext ctx = new WebAppContext();
.
.
ctx.getServletContext().setAttribute(ADMINS_ACL, adminsAcl);
.
.
}
{code}
* Now any page having *HttpServer.hasAdministratorAccess*() will allow access
to everyone, making this check useless.
{code:java}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response
) throws ServletException, IOException {
// Do the authorization
if (!HttpServer.hasAdministratorAccess(getServletContext(), request,
response)) {
return;
}
.
.
}{code}
[For example See L104
LogLevel.java|https://github.com/apache/hbase/blob/46cb5dfa226892fd2580f26ce9ce77225bd7e67c/hbase-http/src/main/java/org/apache/hadoop/hbase/http/log/LogLevel.java#L104]
* *hasAdministratorAccess()* checks for the following and returns true, in any
case as *ADMIN_ACL* is always *null*
{code:java}
public static boolean hasAdministratorAccess(
ServletContext servletContext, HttpServletRequest request,
HttpServletResponse response) throws IOException {
.
.
if (servletContext.getAttribute(ADMINS_ACL) != null &&
!userHasAdministratorAccess(servletContext, remoteUser)) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "User "
+ remoteUser + " is unauthorized to access this page.");
return false;
}
return true;
}{code}
[See line 1196 in
HttpServer|https://github.com/apache/hbase/blob/46cb5dfa226892fd2580f26ce9ce77225bd7e67c/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java#L1196]
was:
The adminsAcl property can be used to restrict access to certain sections of
the web UI only to a particular set of users/groups. But in hbase, adminAcl
variable for InfoServer is always null, rendering it to not honour any acl set
by the admin. In fact I could not find any property in hbase to specify acl
list for web server.
*Analysis*:
* *InfoSever* object forgets(?) to set any *adminAcl* in the builder object
for http server.
{code:java}
public InfoServer(String name, String bindAddress, int port, boolean findPort,
final Configuration c) {
.
.
HttpServer.Builder builder =
new org.apache.hadoop.hbase.http.HttpServer.Builder();
.
.
this.httpServer = builder.build();
}{code}
[See InfoServer
constructor|https://github.com/apache/hbase/blob/46cb5dfa226892fd2580f26ce9ce77225bd7e67c/hbase-http/src/main/java/org/apache/hadoop/hbase/http/InfoServer.java#L55]
* http server retreives a null value and sets it as adminsAcl, which is passed
to *createWebAppContext*() method
{code:java}
private HttpServer(final Builder b) throws IOException {
.
.
.
this.adminsAcl = b.adminsAcl;
this.webAppContext = createWebAppContext(b.name, b.conf, adminsAcl, appDir);
.
.
}{code}
[See L527
HttpServer.java|https://github.com/apache/hbase/blob/46cb5dfa226892fd2580f26ce9ce77225bd7e67c/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java#L527]
**Solution:**
* This method sets *ADMIN_ACL* attribute for the servlet context to *null*
{code:java}
private static WebAppContext createWebAppContext(String name,
Configuration conf, AccessControlList adminsAcl, final String appDir) {
WebAppContext ctx = new WebAppContext();
.
.
ctx.getServletContext().setAttribute(ADMINS_ACL, adminsAcl);
.
.
}
{code}
* Now any page having *HttpServer.hasAdministratorAccess*() will allow access
to everyone, making this check useless.
{code:java}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response
) throws ServletException, IOException {
// Do the authorization
if (!HttpServer.hasAdministratorAccess(getServletContext(), request,
response)) {
return;
}
.
.
}{code}
[For example See L104
LogLevel.java|https://github.com/apache/hbase/blob/46cb5dfa226892fd2580f26ce9ce77225bd7e67c/hbase-http/src/main/java/org/apache/hadoop/hbase/http/log/LogLevel.java#L104]
* *hasAdministratorAccess()* checks for the following and returns true, in any
case as *ADMIN_ACL* is always *null*
{code:java}
public static boolean hasAdministratorAccess(
ServletContext servletContext, HttpServletRequest request,
HttpServletResponse response) throws IOException {
.
.
if (servletContext.getAttribute(ADMINS_ACL) != null &&
!userHasAdministratorAccess(servletContext, remoteUser)) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "User "
+ remoteUser + " is unauthorized to access this page.");
return false;
}
return true;
}{code}
[See line 1196 in
HttpServer|https://github.com/apache/hbase/blob/46cb5dfa226892fd2580f26ce9ce77225bd7e67c/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java#L1196]
> InfoServer doesnot honour any acl set by the admin
> --------------------------------------------------
>
> Key: HBASE-20472
> URL: https://issues.apache.org/jira/browse/HBASE-20472
> Project: HBase
> Issue Type: Bug
> Components: security, UI
> Reporter: Nihal Jain
> Priority: Critical
>
> The adminsAcl property can be used to restrict access to certain sections of
> the web UI only to a particular set of users/groups. But in hbase, adminAcl
> variable for InfoServer is always null, rendering it to not honour any acl
> set by the admin. In fact I could not find any property in hbase to specify
> acl list for web server.
> *Analysis*:
> * *InfoSever* object forgets(?) to set any *adminAcl* in the builder object
> for http server.
> {code:java}
> public InfoServer(String name, String bindAddress, int port, boolean findPort,
> final Configuration c) {
> .
> .
>
> HttpServer.Builder builder =
> new org.apache.hadoop.hbase.http.HttpServer.Builder();
> .
> .
> this.httpServer = builder.build();
> }{code}
> [See InfoServer
> constructor|https://github.com/apache/hbase/blob/46cb5dfa226892fd2580f26ce9ce77225bd7e67c/hbase-http/src/main/java/org/apache/hadoop/hbase/http/InfoServer.java#L55]
> * http server retreives a null value and sets it as adminsAcl, which is
> passed to *createWebAppContext*() method
> {code:java}
> private HttpServer(final Builder b) throws IOException {
> .
> .
> .
> this.adminsAcl = b.adminsAcl;
> this.webAppContext = createWebAppContext(b.name, b.conf, adminsAcl,
> appDir);
>
> .
> .
> }{code}
> [See L527
> HttpServer.java|https://github.com/apache/hbase/blob/46cb5dfa226892fd2580f26ce9ce77225bd7e67c/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java#L527]
> * This method next sets *ADMIN_ACL* attribute for the servlet context to
> *null*
> {code:java}
> private static WebAppContext createWebAppContext(String name,
> Configuration conf, AccessControlList adminsAcl, final String appDir) {
> WebAppContext ctx = new WebAppContext();
> .
> .
> ctx.getServletContext().setAttribute(ADMINS_ACL, adminsAcl);
> .
> .
> }
> {code}
> * Now any page having *HttpServer.hasAdministratorAccess*() will allow
> access to everyone, making this check useless.
> {code:java}
> @Override
> public void doGet(HttpServletRequest request, HttpServletResponse response
> ) throws ServletException, IOException {
> // Do the authorization
> if (!HttpServer.hasAdministratorAccess(getServletContext(), request,
> response)) {
> return;
> }
> .
> .
> }{code}
> [For example See L104
> LogLevel.java|https://github.com/apache/hbase/blob/46cb5dfa226892fd2580f26ce9ce77225bd7e67c/hbase-http/src/main/java/org/apache/hadoop/hbase/http/log/LogLevel.java#L104]
> * *hasAdministratorAccess()* checks for the following and returns true, in
> any case as *ADMIN_ACL* is always *null*
> {code:java}
> public static boolean hasAdministratorAccess(
> ServletContext servletContext, HttpServletRequest request,
> HttpServletResponse response) throws IOException {
> .
> .
> if (servletContext.getAttribute(ADMINS_ACL) != null &&
> !userHasAdministratorAccess(servletContext, remoteUser)) {
> response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "User "
> + remoteUser + " is unauthorized to access this page.");
> return false;
> }
> return true;
> }{code}
> [See line 1196 in
> HttpServer|https://github.com/apache/hbase/blob/46cb5dfa226892fd2580f26ce9ce77225bd7e67c/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java#L1196]
>
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)