package org.apereo.cas.config; import net.shibboleth.ext.spring.util.SpringSupport; import net.shibboleth.idp.attribute.resolver.AttributeDefinition; import net.shibboleth.idp.attribute.resolver.DataConnector; import net.shibboleth.idp.attribute.resolver.impl.AttributeResolverImpl; import org.apereo.cas.configuration.CasConfigurationProperties; import org.apereo.cas.configuration.support.Beans; import org.apereo.cas.persondir.support.ShibbolethPersonAttributeDao; import org.apereo.services.persondir.IPersonAttributeDao; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.EnumerablePropertySource; import org.springframework.scheduling.annotation.EnableScheduling; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Properties; /** * The {@link ShibbolethAttributeResolverConfiguration}. * * @author Jonathan Johnson * @since 5.0.0 */ @Configuration("shibbolethAttributeResolverConfiguration") @EnableConfigurationProperties(CasConfigurationProperties.class) @EnableScheduling public class ShibbolethAttributeResolverConfiguration { private static final Logger LOGGER = LoggerFactory.getLogger(ShibbolethAttributeResolverConfiguration.class); @Autowired private ApplicationContext applicationContext; @Autowired private ConfigurableEnvironment environment; @Autowired private CasConfigurationProperties casProperties; @Bean public IPersonAttributeDao attributeRepository() { try { final PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer(); final Map<String, Object> result = new HashMap<>(); environment.getPropertySources().forEach(s -> { if (s instanceof EnumerablePropertySource<?>) { final EnumerablePropertySource<?> ps = (EnumerablePropertySource<?>) s; Arrays.asList(ps.getPropertyNames()).forEach(key -> result.put(key, ps.getProperty(key))); } }); final Properties p = new Properties(); p.putAll(result); cfg.setProperties(p); registerBeanIntoApplicationContext(cfg, "shibboleth.PropertySourcesPlaceholderConfigurer"); final ApplicationContext tempApplicationContext = SpringSupport.newContext( getClass().getName(), casProperties.getShibAttributeResolver().getResources(), Collections.singletonList(cfg), Collections.emptyList(), Collections.emptyList(), this.applicationContext ); final Collection<DataConnector> values = BeanFactoryUtils.beansOfTypeIncludingAncestors(tempApplicationContext, DataConnector.class).values(); final Collection<DataConnector> connectors = new HashSet<>(values); final AttributeResolverImpl impl = new AttributeResolverImpl(); impl.setId(getClass().getSimpleName()); impl.setApplicationContext(tempApplicationContext); impl.setAttributeDefinitions(BeanFactoryUtils.beansOfTypeIncludingAncestors(tempApplicationContext, AttributeDefinition.class).values()); impl.setDataConnectors(connectors); if (!impl.isInitialized()) { impl.initialize(); } return new ShibbolethPersonAttributeDao(impl); } catch (final Exception e) { LOGGER.warn(e.getMessage(), e); } return Beans.newStubAttributeRepository(casProperties.getAuthn().getAttributeRepository()); } /** * Register bean into application context. * * @param beanInstance the bean instance * @param name the name */ protected void registerBeanIntoApplicationContext(final Object beanInstance, final String name) { final Object initBean = this.applicationContext.getAutowireCapableBeanFactory().initializeBean(beanInstance, name); final ConfigurableListableBeanFactory factory = (ConfigurableListableBeanFactory) applicationContext.getAutowireCapableBeanFactory(); factory.registerSingleton(name, initBean); } }