001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.http.lib;
019
020import java.io.IOException;
021import java.util.HashMap;
022import java.util.Map;
023import org.apache.hadoop.conf.Configuration;
024import org.apache.hadoop.hbase.HBaseInterfaceAudience;
025import org.apache.hadoop.hbase.http.FilterContainer;
026import org.apache.hadoop.hbase.http.FilterInitializer;
027import org.apache.hadoop.hbase.http.HttpServer;
028import org.apache.hadoop.security.SecurityUtil;
029import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
030import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
031import org.apache.yetus.audience.InterfaceAudience;
032
033/**
034 * This class is copied from Hadoop. Initializes hadoop-auth AuthenticationFilter which provides
035 * support for Kerberos HTTP SPNEGO authentication.
036 * <p>
037 * It enables anonymous access, simple/pseudo and Kerberos HTTP SPNEGO authentication for HBase web
038 * UI endpoints.
039 * <p>
040 * Refer to the <code>core-default.xml</code> file, after the comment 'HTTP Authentication' for
041 * details on the configuration options. All related configuration properties have
042 * 'hadoop.http.authentication.' as prefix.
043 */
044@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)
045public class AuthenticationFilterInitializer extends FilterInitializer {
046
047  static final String PREFIX = "hadoop.http.authentication.";
048
049  /**
050   * Initializes hadoop-auth AuthenticationFilter.
051   * <p>
052   * Propagates to hadoop-auth AuthenticationFilter configuration all Hadoop configuration
053   * properties prefixed with "hadoop.http.authentication."
054   * @param container The filter container
055   * @param conf      Configuration for run-time parameters
056   */
057  @Override
058  public void initFilter(FilterContainer container, Configuration conf) {
059    Map<String, String> filterConfig = getFilterConfigMap(conf, PREFIX);
060
061    container.addFilter("authentication", AuthenticationFilter.class.getName(), filterConfig);
062  }
063
064  public static Map<String, String> getFilterConfigMap(Configuration conf, String prefix) {
065    Map<String, String> filterConfig = new HashMap<String, String>();
066
067    // setting the cookie path to root '/' so it is used for all resources.
068    filterConfig.put(AuthenticationFilter.COOKIE_PATH, "/");
069    Map<String, String> propsWithPrefix = conf.getPropsWithPrefix(prefix);
070
071    for (Map.Entry<String, String> entry : propsWithPrefix.entrySet()) {
072      filterConfig.put(entry.getKey(), entry.getValue());
073    }
074
075    // Resolve _HOST into bind address
076    String bindAddress = conf.get(HttpServer.BIND_ADDRESS);
077    String principal = filterConfig.get(KerberosAuthenticationHandler.PRINCIPAL);
078    if (principal != null) {
079      try {
080        principal = SecurityUtil.getServerPrincipal(principal, bindAddress);
081      } catch (IOException ex) {
082        throw new RuntimeException("Could not resolve Kerberos principal name: " + ex.toString(),
083          ex);
084      }
085      filterConfig.put(KerberosAuthenticationHandler.PRINCIPAL, principal);
086    }
087    return filterConfig;
088  }
089
090}