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 */
018 package org.apache.hadoop.http.lib;
019
020 import java.io.IOException;
021 import java.security.Principal;
022 import java.util.HashMap;
023
024 import javax.servlet.FilterChain;
025 import javax.servlet.FilterConfig;
026 import javax.servlet.ServletException;
027 import javax.servlet.ServletRequest;
028 import javax.servlet.ServletResponse;
029 import javax.servlet.http.HttpServletRequest;
030 import javax.servlet.http.HttpServletRequestWrapper;
031
032 import org.apache.commons.logging.Log;
033 import org.apache.commons.logging.LogFactory;
034 import org.apache.hadoop.conf.Configuration;
035 import org.apache.hadoop.http.FilterContainer;
036 import org.apache.hadoop.http.FilterInitializer;
037
038 import javax.servlet.Filter;
039
040 import static org.apache.hadoop.fs.CommonConfigurationKeys.HADOOP_HTTP_STATIC_USER;
041 import static org.apache.hadoop.fs.CommonConfigurationKeys.DEFAULT_HADOOP_HTTP_STATIC_USER;
042
043 /**
044 * Provides a servlet filter that pretends to authenticate a fake user (Dr.Who)
045 * so that the web UI is usable for a secure cluster without authentication.
046 */
047 public class StaticUserWebFilter extends FilterInitializer {
048 static final String DEPRECATED_UGI_KEY = "dfs.web.ugi";
049
050 private static final Log LOG = LogFactory.getLog(StaticUserWebFilter.class);
051
052 static class User implements Principal {
053 private final String name;
054 public User(String name) {
055 this.name = name;
056 }
057 @Override
058 public String getName() {
059 return name;
060 }
061 @Override
062 public int hashCode() {
063 return name.hashCode();
064 }
065 @Override
066 public boolean equals(Object other) {
067 if (other == this) {
068 return true;
069 } else if (other == null || other.getClass() != getClass()) {
070 return false;
071 }
072 return ((User) other).name.equals(name);
073 }
074 @Override
075 public String toString() {
076 return name;
077 }
078 }
079
080 public static class StaticUserFilter implements Filter {
081 private User user;
082 private String username;
083
084 @Override
085 public void destroy() {
086 // NOTHING
087 }
088
089 @Override
090 public void doFilter(ServletRequest request, ServletResponse response,
091 FilterChain chain
092 ) throws IOException, ServletException {
093 HttpServletRequest httpRequest = (HttpServletRequest) request;
094 // if the user is already authenticated, don't override it
095 if (httpRequest.getRemoteUser() != null) {
096 chain.doFilter(request, response);
097 } else {
098 HttpServletRequestWrapper wrapper =
099 new HttpServletRequestWrapper(httpRequest) {
100 @Override
101 public Principal getUserPrincipal() {
102 return user;
103 }
104 @Override
105 public String getRemoteUser() {
106 return username;
107 }
108 };
109 chain.doFilter(wrapper, response);
110 }
111 }
112
113 @Override
114 public void init(FilterConfig conf) throws ServletException {
115 this.username = conf.getInitParameter(HADOOP_HTTP_STATIC_USER);
116 this.user = new User(username);
117 }
118
119 }
120
121 @Override
122 public void initFilter(FilterContainer container, Configuration conf) {
123 HashMap<String, String> options = new HashMap<String, String>();
124
125 String username = getUsernameFromConf(conf);
126 options.put(HADOOP_HTTP_STATIC_USER, username);
127
128 container.addFilter("static_user_filter",
129 StaticUserFilter.class.getName(),
130 options);
131 }
132
133 /**
134 * Retrieve the static username from the configuration.
135 */
136 static String getUsernameFromConf(Configuration conf) {
137 String oldStyleUgi = conf.get(DEPRECATED_UGI_KEY);
138 if (oldStyleUgi != null) {
139 // We can't use the normal configuration deprecation mechanism here
140 // since we need to split out the username from the configured UGI.
141 LOG.warn(DEPRECATED_UGI_KEY + " should not be used. Instead, use " +
142 HADOOP_HTTP_STATIC_USER + ".");
143 String[] parts = oldStyleUgi.split(",");
144 return parts[0];
145 } else {
146 return conf.get(HADOOP_HTTP_STATIC_USER,
147 DEFAULT_HADOOP_HTTP_STATIC_USER);
148 }
149 }
150
151 }