java - Starter autoconfig bean 始终优先于自定义 autoconfig bean

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

我正在尝试制作一个自定义 Spring Boot 启动器,多个项目将使用它来向 Azure AD 进行身份验证。所有 Azure AD 配置都已设置,并且使用 Azure AD 的所有设置硬编码的单个项目也可以正常工作。现在我正在尝试将这些设置移动到自定义 Spring Boot 启动器中,以便多个项目可以使用它。它在大多数情况下都有效,除了一件事:为自定义 AADAppRoleStatelessAuthenticationFilter 移动 bean 配置 .如果我将我的自定义实现(CustomAADAppRoleStatelessAuthFilter)硬编码在实际的实现项目中,一切正常,只有 CustomAADAppRoleStatelessAuthFilter已创建,但一旦我将它移到自定义启动器中,我只会得到 AADAppRoleStatelessAuthenticationFilter反而。

请注意,我的 CustomAADAppRoleStatelessAuthFilter扩展启动器的
AADAppRoleStatelessAuthenticationFilter .
AADAppRoleStatelessAuthenticationFilter 的自动配置在 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 ) 中是:

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

没有@AutoConfigureBefore(AADAuthenticationFilterAutoConfiguration.class)作品。

此外,如果我将自定义 bean 上的条件更改为子类型 ( @ConditionalOnMissingBean(CustomAADAppRoleStatelessAuthFilter.class) ),则会创建两种类型,并且我可以 Autowiring 我的 CustomAwareAADAppRoleStatelessAuthFilter并将其放入我的WebSecurityConfigurerAdapter ,但事情仍然无法正常工作。我调试了一下,发现 CustomAADAppRoleStatelessAuthFilterADAppRoleStatelessAuthenticationFilter 的唯一 bean输入我的 Spring 安全过滤器链 ,但是一旦“附加过滤器链的结束”完成并且“原始链继续”,我发现 ADAppRoleStatelessAuthenticationFilter已经开除了! 当然它会抛出一个错误,因为我的 CustomAADAppRoleStatelessAuthFilter已经做了一些事情来定制UserPrincipal .我不知道 ADAppRoleStatelessAuthenticationFilter 在哪里被添加到任何过滤器链中,即使我标记了我的 CustomAADAppRoleStatelessAuthFilter bean 类@Primary , 首发 ADAppRoleStatelessAuthenticationFilter仍将被使用。

唯一有效的“解决方案”是定义 CustomAADAppRoleStatelessAuthFilter在实际实现项目中而不是自定义启动项目中,或排除AADAuthenticationFilterAutoConfiguration在我实际实现项目的@SpringBootApplication注释(甚至不排除它,基于属性的方式有效)。

有没有办法制作AADAuthenticationFilterAutoConfiguration小号 ADAppRoleStatelessAuthenticationFilter bean 定义后退?因为@AutoConfigureBefore(AADAuthenticationFilterAutoConfiguration.class)在具有我的 CustomAADAppRoleStatelessAuthFilter 的自定义自动配置类上定义不起作用,并且所有实现项目都明确排除 AADAuthenticationFilterAutoConfiguration不是最理想的解决方案(尽管至少使用该解决方案,他们并不都需要为 CustomAADAppRoleStatelessAuthFilter 声明自己的 bean 定义)。

最佳答案

您是否尝试过使用 @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 应该优先于另一个。

关于java - Starter autoconfig bean 始终优先于自定义 autoconfig bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59777396/

相关文章:

java - 如何获取传递给 HTTP POST 的参数

java - Spring Boot 进度报告

spring - 如何使用 Spring Boot 自动重定向到 https

java - 从 Spring Boot 执行 Neo4j 密码查询

python - 如何根据服务主体 ID 限制对 azure 函数的访问

azure - az ad sp create-for-rbac --role ="Contributor">> 缺少订阅,

java - 如何在 Java 中安装附加包?

java - Tomcat 中 JNDI 的 Java Mail API 配置文档

java - POI 朗读Word文档中的句子

azure - 启用了 Active Directory 身份验证的应用程序服务无法运行