入门级自动配置Bean始终优先于自定义自动配置Bean - java

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

请注意,我的CustomAADAppRoleStatelessAuthFilter扩展了初学者的
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)中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*/);
}

@AutoConfigureBefore(AADAuthenticationFilterAutoConfiguration.class)无效。

另外,如果我将自定义bean的条件更改为子类型(@ConditionalOnMissingBean(CustomAADAppRoleStatelessAuthFilter.class)),则会创建两种类型,并且可以自动连接CustomAwareAADAppRoleStatelessAuthFilter并将其放在我的WebSecurityConfigurerAdapter中,但仍然无法正常工作。我调试了东西,发现CustomAADAppRoleStatelessAuthFilter是我的Spring安全性过滤器链中唯一的ADAppRoleStatelessAuthenticationFilter类型的bean,但是一旦“附加过滤器链的末端”完成并且“原始链继续进行”,我发现ADAppRoleStatelessAuthenticationFilter已触发!当然,这会引发错误,因为我的CustomAADAppRoleStatelessAuthFilter已经完成了自定义UserPrincipal的工作。我无法弄清楚ADAppRoleStatelessAuthenticationFilter会被添加到任何过滤器链中的哪个位置,即使我用CustomAADAppRoleStatelessAuthFilter标记了@Primary bean,仍将使用启动器ADAppRoleStatelessAuthenticationFilter

唯一有效的“解决方案”是在实际的实施项目中定义CustomAADAppRoleStatelessAuthFilter而不是自定义的入门项目,或者在我的实际实施项目的AADAuthenticationFilterAutoConfiguration批注中排除@SpringBootApplication(甚至不排除该属性方式有效)。

有没有办法让AADAuthenticationFilterAutoConfigurationADAppRoleStatelessAuthenticationFilter 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应该优先于另一个。

IntelliJ Spring MVC教程部署 - java

我尝试了tutorial,当我尝试部署webapp(IntelliJ 13.1.4 Ultimate)时,出现了一个奇怪的错误,如下面的屏幕快照所示。解决此错误的方法是什么? org.jdom.input.JDOMParseException: Error on line 742: The content of elements must consist o…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java-如何将此字符串转换为日期? - java

我从服务器收到此消息,我不明白T和Z的含义,2012-08-24T09:59:59Z将此字符串转换为Date对象的正确SimpleDateFormat模式是什么? java大神给出的解决方案 这是ISO 8601标准。您可以使用SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM…

春季安全值得付出努力 - java

我一直在关注春季安全性,并注意到它是多么大的包装。我想知道是否值得花一些时间来加强这一点。Spring Security 2.0+为您节省了大量时间,还是以任何方式简化了您的项目? java参考方案 几年前,我考虑将其用于Spring项目,并选择了它,因为它是一个非常繁琐的框架,恕我直言,它提供的灵活性不是必需的。 (据我估计)减少我们自己的身份验证/授权的…

Java:从类中查找项目名称 - java

仅通过类的实例,如何使用Java反射或类似方法查找项目名称?如果不是,项目名称(我真正想要的是)可以找到程序包名称吗? 参考方案 项目只是IDE使用的简单组织工具,因此项目名称不是类或JVM中包含的信息。要获取软件包,请使用Class#getPackage()。然后,可以调用Package#getName()将包作为您在代码的包声明中看到的String来获取…