I'm trying to make a custom spring boot starter that will be used by multiple projects to authenticate with Azure AD. All the Azure AD config has been set up and an individual project hardcoded with all the settings to work with Azure AD works fine too. Now I'm trying to move these settings into a custom Spring Boot starter so that multiple projects can use it. It works for the most part, except for one thing: moving the bean config for a custom AADAppRoleStatelessAuthenticationFilter
. If I leave my custom implementation (CustomAADAppRoleStatelessAuthFilter
) hardcoded in the actual implementing project, everything works and only CustomAADAppRoleStatelessAuthFilter
is created, but as soon as I move it into the custom starter, I only ever get AADAppRoleStatelessAuthenticationFilter
instead.
Note that my CustomAADAppRoleStatelessAuthFilter
extends the starter's
AADAppRoleStatelessAuthenticationFilter
.
The autoconfig for AADAppRoleStatelessAuthenticationFilter
in the azure-spring-boot project (https://github.com/microsoft/azure-spring-boot/blob/master/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/aad/AADAuthenticationFilterAutoConfiguration.java) is:
@Bean
@ConditionalOnMissingBean(AADAppRoleStatelessAuthenticationFilter.class)
@ConditionalOnProperty(prefix = PROPERTY_PREFIX, value = PROPERTY_SESSION_STATELESS, havingValue = "true")
public AADAppRoleStatelessAuthenticationFilter azureADStatelessAuthFilter(ResourceRetriever resourceRetriever) {
//bean details omitted
}
My custom autoconfig that should replace the above is as follows:
@Bean
@ConditionalOnMissingBean(AADAppRoleStatelessAuthenticationFilter.class)
@ConditionalOnProperty(prefix = PROPERTY_PREFIX, value = PROPERTY_SESSION_STATELESS, havingValue = "true")
public AADAppRoleStatelessAuthenticationFilter customAADAppRoleStatelessAuthFilter(
ResourceRetriever resourceRetriever) {
return new CustomAADAppRoleStatelessAuthenticationFilter(/*details omitted*/);
}
No amount of @AutoConfigureBefore(AADAuthenticationFilterAutoConfiguration.class)
works.
Also, if I change the condition on my custom bean to be the subtype (@ConditionalOnMissingBean(CustomAADAppRoleStatelessAuthFilter.class)
), BOTH types get created, and I can autowire my CustomAwareAADAppRoleStatelessAuthFilter
and put it in my WebSecurityConfigurerAdapter
, but things STILL won't work. I debugged things and found that the CustomAADAppRoleStatelessAuthFilter
is the only bean of the ADAppRoleStatelessAuthenticationFilter
type in my spring security filter chain, but that once the 'end of the additional filter chain' has completed and the 'original chain proceeds', I find that the ADAppRoleStatelessAuthenticationFilter
has fired! And of course it throws an error because my CustomAADAppRoleStatelessAuthFilter
has already done things to customize the UserPrincipal
. I can't figure out where the ADAppRoleStatelessAuthenticationFilter
is getting added to any filter chain, and even if I mark my CustomAADAppRoleStatelessAuthFilter
bean with @Primary
, the starter ADAppRoleStatelessAuthenticationFilter
will still be used instead.
The only 'solutions' that have worked are to define the CustomAADAppRoleStatelessAuthFilter
in the actual implementing project instead of the custom starter project, or to exclude the AADAuthenticationFilterAutoConfiguration
in my actual implementing project's @SpringBootApplication
annotation (Not even excluding it the property-based way works).
Is there a way to make AADAuthenticationFilterAutoConfiguration
s ADAppRoleStatelessAuthenticationFilter
bean definition back off? 'Cause @AutoConfigureBefore(AADAuthenticationFilterAutoConfiguration.class)
on my custom auto configuration class that has my CustomAADAppRoleStatelessAuthFilter
definition doesn't work, and having all the implementing projects explicitly exclude AADAuthenticationFilterAutoConfiguration
isn't the most ideal solution (although at least with that solution they don't all need to declare their own bean definition for CustomAADAppRoleStatelessAuthFilter
).
AutoConfiguration classes are run last (meaning after all regular non-autoconfiguration classes) while the order in which Configuration classes are run is indeterminate (except if we use ordering annotations like @Ordered ) To declare a class as an AutoConfiguration they need to be specified as such in the spring.
For example, if the H2 database Jar is present in the classpath and we have not configured any beans related to the database manually, the Spring Boot's auto-configuration feature automatically configures it in the project. We can enable the auto-configuration feature by using the annotation @EnableAutoConfiguration.
Spring Boot auto-configuration attempts to automatically configure your Spring application based on the jar dependencies that you have added. For example, If HSQLDB is on your classpath, and you have not manually configured any database connection beans, then we will auto-configure an in-memory database.
The @ConditionalOnBean and @ConditionalOnMissingBean annotations allow configurations to be skipped based on the presence or absence of specific beans. You can use the value attribute to specify beans by type, or name to specify beans by name.
Have you tried using @Order
and assign your custom bean a higer precedence. By default all the beans gets lowest priority (Ordered.LOWEST_PRECEDENCE
) losing to any other specified order value.
@Order(Ordered.LOWEST_PRECEDENCE - 1)
@Bean
@ConditionalOnMissingBean(AADAppRoleStatelessAuthenticationFilter.class)
@ConditionalOnProperty(prefix = PROPERTY_PREFIX, value = PROPERTY_SESSION_STATELESS, havingValue = "true")
public AADAppRoleStatelessAuthenticationFilter customAADAppRoleStatelessAuthFilter(
ResourceRetriever resourceRetriever) {
return new CustomAADAppRoleStatelessAuthenticationFilter(/*details omitted*/);
}
Can you try putting the @Order(Ordered.LOWEST_PRECEDENCE - 1)
like i mentioned above? Your bean should then take precedence over the other.
Have you tried adding @Primary
to your bean?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With