/* * 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 org.apache.flink.test.util; import org.apache.flink.annotation.Internal; import org.apache.flink.runtime.security.JaasConfiguration; import org.apache.hadoop.security.authentication.util.KerberosUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.security.auth.login.AppConfigurationEntry; import java.util.HashMap; import java.util.Map; /** * {@link TestingJaasConfiguration} for handling the integration test case since it requires to manage * client principal as well as server principals of Hadoop/ZK which expects the host name to be populated * in specific way (localhost vs 127.0.0.1). This provides an abstraction to handle more than one Login Module * since the default {@link JaasConfiguration} behavior only supports global/unique principal identifier */ @Internal public class TestingJaasConfiguration extends JaasConfiguration { private static final Logger LOG = LoggerFactory.getLogger(TestingJaasConfiguration.class); public Map<String, TestingSecurityContext.ClientSecurityConfiguration> clientSecurityConfigurationMap; TestingJaasConfiguration(String keytab, String principal, Map<String, TestingSecurityContext.ClientSecurityConfiguration> clientSecurityConfigurationMap) { super(keytab, principal); this.clientSecurityConfigurationMap = clientSecurityConfigurationMap; } @Override public AppConfigurationEntry[] getAppConfigurationEntry(String applicationName) { LOG.debug("In TestingJaasConfiguration - Application Requested: {}", applicationName); AppConfigurationEntry[] appConfigurationEntry = super.getAppConfigurationEntry(applicationName); if(clientSecurityConfigurationMap != null && clientSecurityConfigurationMap.size() > 0) { if(clientSecurityConfigurationMap.containsKey(applicationName)) { LOG.debug("In TestingJaasConfiguration - Application: {} found in the supplied context", applicationName); TestingSecurityContext.ClientSecurityConfiguration conf = clientSecurityConfigurationMap.get(applicationName); if(appConfigurationEntry != null && appConfigurationEntry.length > 0) { for(int count=0; count < appConfigurationEntry.length; count++) { AppConfigurationEntry ace = appConfigurationEntry[count]; if (ace.getOptions().containsKey("keyTab")) { String keyTab = conf.getKeytab(); String principal = conf.getPrincipal(); LOG.debug("In TestingJaasConfiguration - Application: {} from the supplied context will " + "use Client Specific Keytab: {} and Principal: {}", applicationName, keyTab, principal); Map<String, String> newKeytabKerberosOptions = new HashMap<>(); newKeytabKerberosOptions.putAll(getKeytabKerberosOptions()); newKeytabKerberosOptions.put("keyTab", keyTab); newKeytabKerberosOptions.put("principal", principal); AppConfigurationEntry keytabKerberosAce = new AppConfigurationEntry( KerberosUtil.getKrb5LoginModuleName(), AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, newKeytabKerberosOptions); appConfigurationEntry = new AppConfigurationEntry[] {keytabKerberosAce}; LOG.debug("---->Login Module is using Keytab based configuration<------"); LOG.debug("Login Module Name: " + keytabKerberosAce.getLoginModuleName()); LOG.debug("Control Flag: " + keytabKerberosAce.getControlFlag()); LOG.debug("Options: " + keytabKerberosAce.getOptions()); } } } } } return appConfigurationEntry; } }