Reputation: 321
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
Upvotes: 1
Views: 779
Reputation: 3293
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 {
...
}
Upvotes: 1