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.http.lib; 019 020import java.io.IOException; 021import java.security.Principal; 022import java.util.HashMap; 023 024import javax.servlet.FilterChain; 025import javax.servlet.FilterConfig; 026import javax.servlet.ServletException; 027import javax.servlet.ServletRequest; 028import javax.servlet.ServletResponse; 029import javax.servlet.http.HttpServletRequest; 030import javax.servlet.http.HttpServletRequestWrapper; 031 032import org.apache.commons.logging.Log; 033import org.apache.commons.logging.LogFactory; 034import org.apache.hadoop.conf.Configuration; 035import org.apache.hadoop.http.FilterContainer; 036import org.apache.hadoop.http.FilterInitializer; 037 038import javax.servlet.Filter; 039 040import static org.apache.hadoop.fs.CommonConfigurationKeys.HADOOP_HTTP_STATIC_USER; 041import 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 */ 047public 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}