I have the following class I plan on using to autowire an instance of a Spring class named AADAppRoleStatelessAuthenticationFilter:
import com.microsoft.azure.spring.autoconfigure.aad.AADAppRoleStatelessAuthenticationFilter; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Component @PropertySource("classpath:default-integration.yml") @Getter @AllArgsConstructor @NoArgsConstructor public class AADFilterManager { @Autowired private AADAppRoleStatelessAuthenticationFilter aadAppRoleStatelessAuthenticationFilter; }
Although the default-integration.yml file is well placed under /resources (no ‘FileNotFoundException’ is thrown), it seems like during the application start-up, Spring, for whatever reason, is not able to read it’s content (or disregards it while trying to initialize aadAppRoleStatelessAuthenticationFilter).
It throws errors related to missing properties, which do exist (if I move the properties as they are into the application.yml file – the autowiring completes successfully).
Field aadAppRoleStatelessAuthenticationFilter in com.security.AADFilterManager required a bean of type 'com.microsoft.azure.spring.autoconfigure.aad.AADAppRoleStatelessAuthenticationFilter' that could not be found. The injection point has the following annotations: - @org.springframework.beans.factory.annotation.Autowired(required=true) The following candidates were found but could not be injected: - Bean method 'azureADStatelessAuthFilter' in 'AADAuthenticationFilterAutoConfiguration' not loaded because @ConditionalOnProperty (azure.activedirectory.client-id) did not find property 'client-id'
My default-integration file:
spring: security: oauth2: client: registration: azure: client-id: B client-secret: C azure: activedirectory: tenant-id: A client-id: B client-secret: C session-stateless: true app-id-uri: D user-group: allowed-groups: Users
Advertisement
Answer
Yes I ran into exactly this issue, this is how I resolved it.
First, you need to define a YamlPropertySourceFactory class:
import java.io.FileNotFoundException; import java.io.IOException; import java.util.Properties; import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; import org.springframework.core.env.PropertiesPropertySource; import org.springframework.core.env.PropertySource; import org.springframework.core.io.support.EncodedResource; import org.springframework.core.io.support.PropertySourceFactory; import org.springframework.lang.Nullable; public class YamlPropertySourceFactory implements PropertySourceFactory { @Override public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException { Properties propertiesFromYaml = loadYamlIntoProperties(resource); String sourceName = name != null ? name : resource.getResource().getFilename(); return new PropertiesPropertySource(sourceName, propertiesFromYaml); } private Properties loadYamlIntoProperties(EncodedResource resource) throws FileNotFoundException { try { YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean(); factory.setResources(resource.getResource()); factory.afterPropertiesSet(); return factory.getObject(); } catch (IllegalStateException e) { // for ignoreResourceNotFound Throwable cause = e.getCause(); if (cause instanceof FileNotFoundException) throw (FileNotFoundException) e.getCause(); throw e; } } }
Now you can use this on the beans where you want to use a yaml file as your PropertySource. For example:
@Configuration @PropertySource(factory = YamlPropertySourceFactory.class, value = "classpath:datasource.yml") @ConfigurationProperties(prefix = "datasource") public class DatasourceConfiguration { ... }