| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package backtype.storm.security.auth; |
| |
| import backtype.storm.Config; |
| import javax.security.auth.login.Configuration; |
| import javax.security.auth.login.AppConfigurationEntry; |
| import javax.security.auth.Subject; |
| import java.security.NoSuchAlgorithmException; |
| import java.security.URIParameter; |
| |
| import backtype.storm.security.INimbusCredentialPlugin; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.net.URI; |
| import java.util.Collection; |
| import java.util.Set; |
| import java.util.HashSet; |
| import java.util.Map; |
| import java.util.concurrent.ExecutorService; |
| |
| public class AuthUtils { |
| private static final Logger LOG = LoggerFactory.getLogger(AuthUtils.class); |
| public static final String LOGIN_CONTEXT_SERVER = "StormServer"; |
| public static final String LOGIN_CONTEXT_CLIENT = "StormClient"; |
| public static final String SERVICE = "storm_thrift_server"; |
| |
| /** |
| * Construct a JAAS configuration object per storm configuration file |
| * @param storm_conf Storm configuration |
| * @return JAAS configuration object |
| */ |
| public static Configuration GetConfiguration(Map storm_conf) { |
| Configuration login_conf = null; |
| |
| //find login file configuration from Storm configuration |
| String loginConfigurationFile = (String)storm_conf.get("java.security.auth.login.config"); |
| if ((loginConfigurationFile != null) && (loginConfigurationFile.length()>0)) { |
| File config_file = new File(loginConfigurationFile); |
| if (! config_file.canRead()) { |
| throw new RuntimeException("File " + loginConfigurationFile + |
| " cannot be read."); |
| } |
| try { |
| URI config_uri = config_file.toURI(); |
| login_conf = Configuration.getInstance("JavaLoginConfig", new URIParameter(config_uri)); |
| } catch (Exception ex) { |
| throw new RuntimeException(ex); |
| } |
| } |
| |
| return login_conf; |
| } |
| |
| /** |
| * Construct a principal to local plugin |
| * @param storm_conf storm configuration |
| * @return the plugin |
| */ |
| public static IPrincipalToLocal GetPrincipalToLocalPlugin(Map storm_conf) { |
| IPrincipalToLocal ptol = null; |
| try { |
| String ptol_klassName = (String) storm_conf.get(Config.STORM_PRINCIPAL_TO_LOCAL_PLUGIN); |
| Class klass = Class.forName(ptol_klassName); |
| ptol = (IPrincipalToLocal)klass.newInstance(); |
| ptol.prepare(storm_conf); |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| return ptol; |
| } |
| |
| /** |
| * Construct a group mapping service provider plugin |
| * @param storm_conf storm configuration |
| * @return the plugin |
| */ |
| public static IGroupMappingServiceProvider GetGroupMappingServiceProviderPlugin(Map storm_conf) { |
| IGroupMappingServiceProvider gmsp = null; |
| try { |
| String gmsp_klassName = (String) storm_conf.get(Config.STORM_GROUP_MAPPING_SERVICE_PROVIDER_PLUGIN); |
| Class klass = Class.forName(gmsp_klassName); |
| gmsp = (IGroupMappingServiceProvider)klass.newInstance(); |
| gmsp.prepare(storm_conf); |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| return gmsp; |
| } |
| |
| /** |
| * Get all of the configured Credential Renwer Plugins. |
| * @param conf the storm configuration to use. |
| * @return the configured credential renewers. |
| */ |
| public static Collection<ICredentialsRenewer> GetCredentialRenewers(Map conf) { |
| try { |
| Set<ICredentialsRenewer> ret = new HashSet<ICredentialsRenewer>(); |
| Collection<String> clazzes = (Collection<String>)conf.get(Config.NIMBUS_CREDENTIAL_RENEWERS); |
| if (clazzes != null) { |
| for (String clazz : clazzes) { |
| ICredentialsRenewer inst = (ICredentialsRenewer)Class.forName(clazz).newInstance(); |
| inst.prepare(conf); |
| ret.add(inst); |
| } |
| } |
| return ret; |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| /** |
| * Get all the Nimbus Auto cred plugins. |
| * @param conf nimbus configuration to use. |
| * @return nimbus auto credential plugins. |
| */ |
| public static Collection<INimbusCredentialPlugin> getNimbusAutoCredPlugins(Map conf) { |
| try { |
| Set<INimbusCredentialPlugin> ret = new HashSet<INimbusCredentialPlugin>(); |
| Collection<String> clazzes = (Collection<String>)conf.get(Config.NIMBUS_AUTO_CRED_PLUGINS); |
| if (clazzes != null) { |
| for (String clazz : clazzes) { |
| INimbusCredentialPlugin inst = (INimbusCredentialPlugin)Class.forName(clazz).newInstance(); |
| inst.prepare(conf); |
| ret.add(inst); |
| } |
| } |
| return ret; |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| /** |
| * Get all of the configured AutoCredential Plugins. |
| * @param storm_conf the storm configuration to use. |
| * @return the configured auto credentials. |
| */ |
| public static Collection<IAutoCredentials> GetAutoCredentials(Map storm_conf) { |
| try { |
| Set<IAutoCredentials> autos = new HashSet<IAutoCredentials>(); |
| Collection<String> clazzes = (Collection<String>)storm_conf.get(Config.TOPOLOGY_AUTO_CREDENTIALS); |
| if (clazzes != null) { |
| for (String clazz : clazzes) { |
| IAutoCredentials a = (IAutoCredentials)Class.forName(clazz).newInstance(); |
| a.prepare(storm_conf); |
| autos.add(a); |
| } |
| } |
| LOG.info("Got AutoCreds "+autos); |
| return autos; |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| /** |
| * Populate a subject from credentials using the IAutoCredentials. |
| * @param subject the subject to populate or null if a new Subject should be created. |
| * @param autos the IAutoCredentials to call to populate the subject. |
| * @param credentials the credentials to pull from |
| * @return the populated subject. |
| */ |
| public static Subject populateSubject(Subject subject, Collection<IAutoCredentials> autos, Map<String,String> credentials) { |
| try { |
| if (subject == null) { |
| subject = new Subject(); |
| } |
| for (IAutoCredentials autoCred : autos) { |
| autoCred.populateSubject(subject, credentials); |
| } |
| return subject; |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| /** |
| * Update a subject from credentials using the IAutoCredentials. |
| * @param subject the subject to update |
| * @param autos the IAutoCredentials to call to update the subject. |
| * @param credentials the credentials to pull from |
| */ |
| public static void updateSubject(Subject subject, Collection<IAutoCredentials> autos, Map<String,String> credentials) { |
| if (subject == null) { |
| throw new RuntimeException("The subject cannot be null when updating a subject with credentials"); |
| } |
| |
| try { |
| for (IAutoCredentials autoCred : autos) { |
| autoCred.updateSubject(subject, credentials); |
| } |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| /** |
| * Construct a transport plugin per storm configuration |
| * @param storm_conf storm configuration |
| * @return |
| */ |
| public static ITransportPlugin GetTransportPlugin(ThriftConnectionType type, Map storm_conf, Configuration login_conf) { |
| ITransportPlugin transportPlugin = null; |
| try { |
| String transport_plugin_klassName = type.getTransportPlugin(storm_conf); |
| Class klass = Class.forName(transport_plugin_klassName); |
| transportPlugin = (ITransportPlugin)klass.newInstance(); |
| transportPlugin.prepare(type, storm_conf, login_conf); |
| } catch(Exception e) { |
| throw new RuntimeException(e); |
| } |
| return transportPlugin; |
| } |
| |
| private static IHttpCredentialsPlugin GetHttpCredentialsPlugin(Map conf, |
| String klassName) { |
| IHttpCredentialsPlugin plugin = null; |
| try { |
| Class klass = Class.forName(klassName); |
| plugin = (IHttpCredentialsPlugin)klass.newInstance(); |
| plugin.prepare(conf); |
| } catch(Exception e) { |
| throw new RuntimeException(e); |
| } |
| return plugin; |
| } |
| |
| /** |
| * Construct an HttpServletRequest credential plugin specified by the UI |
| * storm configuration |
| * @param conf storm configuration |
| * @return the plugin |
| */ |
| public static IHttpCredentialsPlugin GetUiHttpCredentialsPlugin(Map conf) { |
| String klassName = (String)conf.get(Config.UI_HTTP_CREDS_PLUGIN); |
| return AuthUtils.GetHttpCredentialsPlugin(conf, klassName); |
| } |
| |
| /** |
| * Construct an HttpServletRequest credential plugin specified by the DRPC |
| * storm configuration |
| * @param conf storm configuration |
| * @return the plugin |
| */ |
| public static IHttpCredentialsPlugin GetDrpcHttpCredentialsPlugin(Map conf) { |
| String klassName = (String)conf.get(Config.DRPC_HTTP_CREDS_PLUGIN); |
| return AuthUtils.GetHttpCredentialsPlugin(conf, klassName); |
| } |
| |
| public static String get(Configuration configuration, String section, String key) throws IOException { |
| AppConfigurationEntry configurationEntries[] = configuration.getAppConfigurationEntry(section); |
| if (configurationEntries == null) { |
| String errorMessage = "Could not find a '"+ section + "' entry in this configuration."; |
| throw new IOException(errorMessage); |
| } |
| |
| for(AppConfigurationEntry entry: configurationEntries) { |
| Object val = entry.getOptions().get(key); |
| if (val != null) |
| return (String)val; |
| } |
| return null; |
| } |
| } |