入门级自动配置bean始终优先于自定义自动配置bean

时间:2020-01-16 20:32:13

标签: java spring-boot azure-active-directory spring-boot-starter

我正在尝试制作一个自定义的Spring Boot启动程序,该启动程序将由多个项目用于通过Azure AD进行身份验证。已经设置了所有Azure AD配置,并且使用所有设置进行硬编码的单个项目都可以与Azure AD一起正常工作。现在,我试图将这些设置移动到自定义的Spring Boot启动程序中,以便多个项目可以使用它。它在大多数情况下有效,除了以下几点:为自定义AADAppRoleStatelessAuthenticationFilter 移动Bean配置。如果我将自定义实现(CustomAADAppRoleStatelessAuthFilter)保留在实际的实现项目中,则一切正常,只有CustomAADAppRoleStatelessAuthFilter被创建,但是一旦将其移入自定义启动程序,我只会得到{{ 1}}。

请注意,我的AADAppRoleStatelessAuthenticationFilter扩展了初学者的 CustomAADAppRoleStatelessAuthFilter

azure-spring-boot项目(https://github.com/microsoft/azure-spring-boot/blob/master/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/aad/AADAuthenticationFilterAutoConfiguration.java)中AADAppRoleStatelessAuthenticationFilter的自动配置为:

AADAppRoleStatelessAuthenticationFilter

我的应替换上面的自定义自动配置如下:

@Bean
@ConditionalOnMissingBean(AADAppRoleStatelessAuthenticationFilter.class)
@ConditionalOnProperty(prefix = PROPERTY_PREFIX, value = PROPERTY_SESSION_STATELESS, havingValue = "true")
public AADAppRoleStatelessAuthenticationFilter azureADStatelessAuthFilter(ResourceRetriever resourceRetriever) {
    //bean details omitted
}

没有多少@Bean @ConditionalOnMissingBean(AADAppRoleStatelessAuthenticationFilter.class) @ConditionalOnProperty(prefix = PROPERTY_PREFIX, value = PROPERTY_SESSION_STATELESS, havingValue = "true") public AADAppRoleStatelessAuthenticationFilter customAADAppRoleStatelessAuthFilter( ResourceRetriever resourceRetriever) { return new CustomAADAppRoleStatelessAuthenticationFilter(/*details omitted*/); } 有效。

此外,如果我将自定义bean的条件更改为子类型(@AutoConfigureBefore(AADAuthenticationFilterAutoConfiguration.class)),则会创建两种类型,并且可以自动连接@ConditionalOnMissingBean(CustomAADAppRoleStatelessAuthFilter.class)并将其放入{{1} },但仍然无法正常工作。我调试了一下程序,发现 CustomAwareAADAppRoleStatelessAuthFilter是我的春季安全性过滤器链中唯一的WebSecurityConfigurerAdapter类型的bean ,但那是“附加过滤器链的末端”已完成,并且“原始链继续进行”,我发现CustomAADAppRoleStatelessAuthFilter被解雇了!当然,这会引发错误,因为我的ADAppRoleStatelessAuthenticationFilter已经做了一些自定义操作ADAppRoleStatelessAuthenticationFilter。我不知道CustomAADAppRoleStatelessAuthFilter会被添加到任何过滤器链中的哪个位置,即使我用UserPrincipal标记我的ADAppRoleStatelessAuthenticationFilter bean,启动器CustomAADAppRoleStatelessAuthFilter仍然是代替。

唯一有效的“解决方案”是在实际的实施项目中定义@Primary而不是自定义的入门项目,或者在我的实际实施项目的{中排除ADAppRoleStatelessAuthenticationFilter {1}}注解(甚至不排除基于属性的方式起作用)。

是否有办法使CustomAADAppRoleStatelessAuthFilter的{​​{1}} bean定义退后? “在具有我的AADAuthenticationFilterAutoConfiguration定义的自定义自动配置类上,@SpringBootApplication无效,并且将所有实施项目明确排除在AADAuthenticationFilterAutoConfiguration之外并不是最理想的解决方案(尽管在至少使用该解决方案,他们不需要都为ADAppRoleStatelessAuthenticationFilter声明自己的bean定义。

2 个答案:

答案 0 :(得分:2)

您是否尝试过使用@Order并为自定义bean分配更高的优先级。默认情况下,所有Bean的优先级最低(Ordered.LOWEST_PRECEDENCE)都输给任何其他指定的订单值。

@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*/);
}

您能尝试像我上面提到的那样放置@Order(Ordered.LOWEST_PRECEDENCE - 1)吗?然后,您的bean应该优先于另一个。

答案 1 :(得分:1)

您是否尝试过将@Primary添加到bean中?