This is an automated email from the ASF dual-hosted git repository.

lprimak pushed a commit to branch 3.x
in repository https://gitbox.apache.org/repos/asf/shiro.git

commit 3cc57d3aceed5bb5a3eb15468f9f5cf562e0fde1
Author: lprimak <[email protected]>
AuthorDate: Thu Feb 5 23:51:03 2026 -0600

    fixed spring boot
    fixes #1236
---
 samples/spring-boot-web/pom.xml                    |  5 +-
 .../main/java/org/apache/shiro/samples/WebApp.java |  1 +
 samples/spring-boot/pom.xml                        | 10 +---
 .../ShiroAnnotationProcessorAutoConfiguration.java |  6 +-
 .../autoconfigure/ShiroBeanAutoConfiguration.java  | 20 +++----
 .../ShiroEnvironmentPostProcessor.java             |  9 ++-
 .../spring/ShiroEventBusBeanPostProcessor.java     |  4 ++
 ...tractShiroAnnotationProcessorConfiguration.java |  6 --
 .../config/AbstractShiroBeanConfiguration.java     | 42 -------------
 .../ShiroAnnotationProcessorConfiguration.java     |  5 +-
 .../spring/config/ShiroBeanConfiguration.java      | 23 +++----
 .../shiro/spring/web/ShiroFilterFactoryBean.java   | 39 +-----------
 .../web/ShiroFilterFactoryBeanPostProcessor.java   | 70 ++++++++++++++++++++++
 .../web/config/ShiroWebFilterConfiguration.java    |  7 ++-
 .../spring/web/ShiroFilterFactoryBeanTest.xml      |  3 +
 15 files changed, 119 insertions(+), 131 deletions(-)

diff --git a/samples/spring-boot-web/pom.xml b/samples/spring-boot-web/pom.xml
index 746b25bd9..ad4792115 100644
--- a/samples/spring-boot-web/pom.xml
+++ b/samples/spring-boot-web/pom.xml
@@ -93,9 +93,8 @@
 
         <!--    below dependencies may not be necessary in "real" applications 
-->
         <dependency>
-            <groupId>jakarta.servlet</groupId>
-            <artifactId>jakarta.servlet-api</artifactId>
-            <scope>provided</scope>
+            <groupId>jakarta.annotation</groupId>
+            <artifactId>jakarta.annotation-api</artifactId>
         </dependency>
     </dependencies>
 
diff --git 
a/samples/spring-boot-web/src/main/java/org/apache/shiro/samples/WebApp.java 
b/samples/spring-boot-web/src/main/java/org/apache/shiro/samples/WebApp.java
index c347ed875..4d57f9921 100644
--- a/samples/spring-boot-web/src/main/java/org/apache/shiro/samples/WebApp.java
+++ b/samples/spring-boot-web/src/main/java/org/apache/shiro/samples/WebApp.java
@@ -88,6 +88,7 @@ public class WebApp {
         // need to accept POSTs from the login form
         chainDefinition.addPathDefinition("/login.html", "authc");
         chainDefinition.addPathDefinition("/logout", "logout");
+        chainDefinition.addPathDefinition("/**", "anon");
         return chainDefinition;
     }
 
diff --git a/samples/spring-boot/pom.xml b/samples/spring-boot/pom.xml
index 09b95182d..aa5e912c9 100644
--- a/samples/spring-boot/pom.xml
+++ b/samples/spring-boot/pom.xml
@@ -58,15 +58,9 @@
             <groupId>jakarta.annotation</groupId>
             <artifactId>jakarta.annotation-api</artifactId>
         </dependency>
-
-        <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-slf4j2-impl</artifactId>
-            <scope>runtime</scope>
-        </dependency>
         <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-core</artifactId>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
             <scope>runtime</scope>
         </dependency>
     </dependencies>
diff --git 
a/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroAnnotationProcessorAutoConfiguration.java
 
b/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroAnnotationProcessorAutoConfiguration.java
index b17fa1b12..82c1f11a6 100644
--- 
a/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroAnnotationProcessorAutoConfiguration.java
+++ 
b/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroAnnotationProcessorAutoConfiguration.java
@@ -39,13 +39,11 @@ import org.springframework.context.annotation.DependsOn;
 @Configuration
 @ConditionalOnProperty(name = "shiro.annotations.enabled", matchIfMissing = 
true)
 public class ShiroAnnotationProcessorAutoConfiguration extends 
AbstractShiroAnnotationProcessorConfiguration {
-
     @Bean
     @DependsOn("lifecycleBeanPostProcessor")
     @ConditionalOnMissingBean(name = 
AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME)
-    @Override
-    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
-        return super.defaultAdvisorAutoProxyCreator();
+    public static DefaultAdvisorAutoProxyCreator 
defaultAdvisorAutoProxyCreator() {
+        return new DefaultAdvisorAutoProxyCreator();
     }
 
     @Bean
diff --git 
a/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroBeanAutoConfiguration.java
 
b/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroBeanAutoConfiguration.java
index 9e9cbe1c3..3adf45128 100644
--- 
a/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroBeanAutoConfiguration.java
+++ 
b/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroBeanAutoConfiguration.java
@@ -19,8 +19,8 @@
 package org.apache.shiro.spring.boot.autoconfigure;
 
 import org.apache.shiro.event.EventBus;
+import org.apache.shiro.event.support.DefaultEventBus;
 import org.apache.shiro.spring.LifecycleBeanPostProcessor;
-import org.apache.shiro.spring.config.AbstractShiroBeanConfiguration;
 import org.apache.shiro.spring.ShiroEventBusBeanPostProcessor;
 import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -32,26 +32,24 @@ import org.springframework.context.annotation.Configuration;
  */
 @Configuration
 @ConditionalOnProperty(name = "shiro.enabled", matchIfMissing = true)
-public class ShiroBeanAutoConfiguration extends AbstractShiroBeanConfiguration 
{
+@SuppressWarnings("checkstyle:HideUtilityClassConstructor")
+public class ShiroBeanAutoConfiguration {
 
     @Bean
     @ConditionalOnMissingBean
-    @Override
-    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
-        return super.lifecycleBeanPostProcessor();
+    public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
+        return new LifecycleBeanPostProcessor();
     }
 
     @Bean
     @ConditionalOnMissingBean
-    @Override
-    protected EventBus eventBus() {
-        return super.eventBus();
+    public static EventBus eventBus(ShiroEventBusBeanPostProcessor processor) {
+        return processor.getEventBus();
     }
 
     @Bean
     @ConditionalOnMissingBean
-    @Override
-    public ShiroEventBusBeanPostProcessor 
shiroEventBusAwareBeanPostProcessor() {
-        return super.shiroEventBusAwareBeanPostProcessor();
+    public static ShiroEventBusBeanPostProcessor 
shiroEventBusAwareBeanPostProcessor() {
+        return new ShiroEventBusBeanPostProcessor(new DefaultEventBus());
     }
 }
diff --git 
a/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroEnvironmentPostProcessor.java
 
b/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroEnvironmentPostProcessor.java
index 94d161fa3..e253d4b71 100644
--- 
a/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroEnvironmentPostProcessor.java
+++ 
b/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroEnvironmentPostProcessor.java
@@ -20,13 +20,13 @@ package org.apache.shiro.spring.config.web.autoconfigure;
 
 import org.springframework.boot.EnvironmentPostProcessor;
 import org.springframework.boot.SpringApplication;
+import org.springframework.core.PriorityOrdered;
 import org.springframework.core.env.ConfigurableEnvironment;
 import org.springframework.core.env.MapPropertySource;
 
 import java.util.Collections;
 
-class ShiroEnvironmentPostProcessor implements EnvironmentPostProcessor {
-
+class ShiroEnvironmentPostProcessor implements EnvironmentPostProcessor, 
PriorityOrdered {
     @Override
     public void postProcessEnvironment(ConfigurableEnvironment environment, 
SpringApplication application) {
         // force the use of the ant path matcher
@@ -34,4 +34,9 @@ class ShiroEnvironmentPostProcessor implements 
EnvironmentPostProcessor {
                 .addFirst(new MapPropertySource("shiro",
                         
Collections.singletonMap("spring.mvc.pathmatch.matching-strategy", 
"ant_path_matcher")));
     }
+
+    @Override
+    public int getOrder() {
+        return LOWEST_PRECEDENCE - 2;
+    }
 }
diff --git 
a/support/spring/src/main/java/org/apache/shiro/spring/ShiroEventBusBeanPostProcessor.java
 
b/support/spring/src/main/java/org/apache/shiro/spring/ShiroEventBusBeanPostProcessor.java
index f0a21059f..a44c904d2 100644
--- 
a/support/spring/src/main/java/org/apache/shiro/spring/ShiroEventBusBeanPostProcessor.java
+++ 
b/support/spring/src/main/java/org/apache/shiro/spring/ShiroEventBusBeanPostProcessor.java
@@ -71,4 +71,8 @@ public class ShiroEventBusBeanPostProcessor implements 
BeanPostProcessor, Priori
     public int getOrder() {
         return LOWEST_PRECEDENCE - 1;
     }
+
+    public EventBus getEventBus() {
+        return eventBus;
+    }
 }
diff --git 
a/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroAnnotationProcessorConfiguration.java
 
b/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroAnnotationProcessorConfiguration.java
index 679d205d7..cd31ad668 100644
--- 
a/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroAnnotationProcessorConfiguration.java
+++ 
b/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroAnnotationProcessorConfiguration.java
@@ -21,17 +21,11 @@ package org.apache.shiro.spring.config;
 
 import org.apache.shiro.mgt.SecurityManager;
 import 
org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
-import 
org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
 
 /**
  * @since 1.4.0
  */
 public class AbstractShiroAnnotationProcessorConfiguration {
-
-    protected DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
-        return new DefaultAdvisorAutoProxyCreator();
-    }
-
     protected AuthorizationAttributeSourceAdvisor 
authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
         AuthorizationAttributeSourceAdvisor advisor = new 
AuthorizationAttributeSourceAdvisor();
         advisor.setSecurityManager(securityManager);
diff --git 
a/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroBeanConfiguration.java
 
b/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroBeanConfiguration.java
deleted file mode 100644
index b2f087ae8..000000000
--- 
a/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroBeanConfiguration.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.shiro.spring.config;
-
-import org.apache.shiro.event.EventBus;
-import org.apache.shiro.event.support.DefaultEventBus;
-import org.apache.shiro.spring.LifecycleBeanPostProcessor;
-import org.apache.shiro.spring.ShiroEventBusBeanPostProcessor;
-
-/**
- * @since 1.4.0
- */
-public class AbstractShiroBeanConfiguration {
-
-    protected LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
-        return new LifecycleBeanPostProcessor();
-    }
-
-    protected EventBus eventBus() {
-        return new DefaultEventBus();
-    }
-
-    protected ShiroEventBusBeanPostProcessor 
shiroEventBusAwareBeanPostProcessor() {
-        return new ShiroEventBusBeanPostProcessor(eventBus());
-    }
-}
diff --git 
a/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroAnnotationProcessorConfiguration.java
 
b/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroAnnotationProcessorConfiguration.java
index 7f769b21b..e87ef3b3a 100644
--- 
a/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroAnnotationProcessorConfiguration.java
+++ 
b/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroAnnotationProcessorConfiguration.java
@@ -31,11 +31,10 @@ import org.springframework.context.annotation.DependsOn;
  */
 @Configuration
 public class ShiroAnnotationProcessorConfiguration extends 
AbstractShiroAnnotationProcessorConfiguration {
-
     @Bean
     @DependsOn("lifecycleBeanPostProcessor")
-    protected DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
-        return super.defaultAdvisorAutoProxyCreator();
+    public static DefaultAdvisorAutoProxyCreator 
defaultAdvisorAutoProxyCreator() {
+        return new DefaultAdvisorAutoProxyCreator();
     }
 
     @Bean
diff --git 
a/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroBeanConfiguration.java
 
b/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroBeanConfiguration.java
index 21f4ffb59..ba134aa9e 100644
--- 
a/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroBeanConfiguration.java
+++ 
b/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroBeanConfiguration.java
@@ -19,35 +19,30 @@
 package org.apache.shiro.spring.config;
 
 import org.apache.shiro.event.EventBus;
+import org.apache.shiro.event.support.DefaultEventBus;
 import org.apache.shiro.spring.LifecycleBeanPostProcessor;
 import org.apache.shiro.spring.ShiroEventBusBeanPostProcessor;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Role;
-import static 
org.springframework.beans.factory.config.BeanDefinition.ROLE_INFRASTRUCTURE;
 
 /**
  * @since 1.4.0
  */
 @Configuration
-public class ShiroBeanConfiguration extends AbstractShiroBeanConfiguration {
-
+@SuppressWarnings("checkstyle:HideUtilityClassConstructor")
+public class ShiroBeanConfiguration {
     @Bean
-    @Override
-    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
-        return super.lifecycleBeanPostProcessor();
+    public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
+        return new LifecycleBeanPostProcessor();
     }
 
     @Bean
-    @Override
-    @Role(ROLE_INFRASTRUCTURE)
-    protected EventBus eventBus() {
-        return super.eventBus();
+    public static EventBus eventBus(ShiroEventBusBeanPostProcessor processor) {
+        return processor.getEventBus();
     }
 
     @Bean
-    @Override
-    public ShiroEventBusBeanPostProcessor 
shiroEventBusAwareBeanPostProcessor() {
-        return super.shiroEventBusAwareBeanPostProcessor();
+    public static ShiroEventBusBeanPostProcessor 
shiroEventBusAwareBeanPostProcessor() {
+        return new ShiroEventBusBeanPostProcessor(new DefaultEventBus());
     }
 }
diff --git 
a/support/spring/src/main/java/org/apache/shiro/spring/web/ShiroFilterFactoryBean.java
 
b/support/spring/src/main/java/org/apache/shiro/spring/web/ShiroFilterFactoryBean.java
index 0cc22c92a..9b8c71179 100644
--- 
a/support/spring/src/main/java/org/apache/shiro/spring/web/ShiroFilterFactoryBean.java
+++ 
b/support/spring/src/main/java/org/apache/shiro/spring/web/ShiroFilterFactoryBean.java
@@ -39,10 +39,8 @@ import org.apache.shiro.web.servlet.AbstractShiroFilter;
 import org.apache.shiro.web.servlet.OncePerRequestFilter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.BeanInitializationException;
 import org.springframework.beans.factory.FactoryBean;
-import org.springframework.beans.factory.config.BeanPostProcessor;
 
 import jakarta.servlet.Filter;
 import java.util.ArrayList;
@@ -76,12 +74,6 @@ import java.util.Map;
  * While there is a {@link #setFilters(java.util.Map) filters} property that 
allows you to assign a filter beans
  * to the 'pool' of filters available when defining {@link 
#setFilterChainDefinitions(String) filter chains}, it is
  * optional.
- * <p/>
- * This implementation is also a {@link BeanPostProcessor} and will acquire
- * any {@link jakarta.servlet.Filter Filter} beans defined independently in 
your Spring application context.  Upon
- * discovery, they will be automatically added to the {@link 
#setFilters(java.util.Map) map} keyed by the bean ID.
- * That ID can then be used in the filter chain definitions, for example:
- *
  * <pre>
  * &lt;bean id="<b>myCustomFilter</b>" 
class="com.class.that.implements.jakarta.servlet.Filter"/&gt;
  * ...
@@ -120,8 +112,7 @@ import java.util.Map;
  * @since 1.0
  */
 @SuppressWarnings("checkstyle:MethodCount")
-public class ShiroFilterFactoryBean implements FactoryBean<Filter>, 
BeanPostProcessor {
-
+public class ShiroFilterFactoryBean implements FactoryBean<Filter> {
     private static final Logger LOGGER = 
LoggerFactory.getLogger(ShiroFilterFactoryBean.class);
 
     private SecurityManager securityManager;
@@ -573,7 +564,7 @@ public class ShiroFilterFactoryBean implements 
FactoryBean<Filter>, BeanPostProc
         }
     }
 
-    private void applyGlobalPropertiesIfNecessary(Filter filter) {
+    void applyGlobalPropertiesIfNecessary(Filter filter) {
         applyLoginUrlIfNecessary(filter);
         applySuccessUrlIfNecessary(filter);
         applyUnauthorizedUrlIfNecessary(filter);
@@ -583,32 +574,6 @@ public class ShiroFilterFactoryBean implements 
FactoryBean<Filter>, BeanPostProc
         }
     }
 
-    /**
-     * Inspects a bean, and if it implements the {@link Filter} interface, 
automatically adds that filter
-     * instance to the internal {@link #setFilters(java.util.Map) filters map} 
that will be referenced
-     * later during filter chain construction.
-     */
-    @Override
-    public Object postProcessBeforeInitialization(Object bean, String 
beanName) throws BeansException {
-        if (bean instanceof Filter filter) {
-            LOGGER.debug("Found filter chain candidate filter '{}'", beanName);
-            applyGlobalPropertiesIfNecessary(filter);
-            getFilters().put(beanName, filter);
-        } else {
-            LOGGER.trace("Ignoring non-Filter bean '{}'", beanName);
-        }
-        return bean;
-    }
-
-    /**
-     * Does nothing - only exists to satisfy the BeanPostProcessor interface 
and immediately returns the
-     * {@code bean} argument.
-     */
-    @Override
-    public Object postProcessAfterInitialization(Object bean, String beanName) 
throws BeansException {
-        return bean;
-    }
-
     /**
      * Ordinarily the {@code AbstractShiroFilter} must be subclassed to 
additionally perform configuration
      * and initialization behavior.  Because this {@code FactoryBean} 
implementation manually builds the
diff --git 
a/support/spring/src/main/java/org/apache/shiro/spring/web/ShiroFilterFactoryBeanPostProcessor.java
 
b/support/spring/src/main/java/org/apache/shiro/spring/web/ShiroFilterFactoryBeanPostProcessor.java
new file mode 100644
index 000000000..f9eb2e76f
--- /dev/null
+++ 
b/support/spring/src/main/java/org/apache/shiro/spring/web/ShiroFilterFactoryBeanPostProcessor.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shiro.spring.web;
+
+import jakarta.servlet.Filter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import java.util.Map;
+
+/**
+ * This implementation is a {@link BeanPostProcessor} and will acquire
+ * any {@link Filter Filter} beans defined independently in your Spring 
application context.  Upon
+ * discovery, they will be automatically added to the {@link 
ShiroFilterFactoryBean#setFilters(Map) map} keyed by the bean ID.
+ * That ID can then be used in the filter chain definitions, for example:
+ *
+ * @since 3.0.0
+ */
+public class ShiroFilterFactoryBeanPostProcessor implements BeanPostProcessor {
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(ShiroFilterFactoryBeanPostProcessor.class);
+
+    private final ShiroFilterFactoryBean shiroFilterFactoryBean;
+
+    public ShiroFilterFactoryBeanPostProcessor(ShiroFilterFactoryBean 
shiroFilterFactoryBean) {
+        this.shiroFilterFactoryBean = shiroFilterFactoryBean;
+    }
+
+    /**
+     * Inspects a bean, and if it implements the {@link Filter} interface, 
automatically adds that filter
+     * instance to the internal {@link ShiroFilterFactoryBean#setFilters(Map) 
filters map} that will be referenced
+     * later during filter chain construction.
+     */
+    @Override
+    public Object postProcessBeforeInitialization(Object bean, String 
beanName) throws BeansException {
+        if (bean instanceof Filter filter) {
+            LOGGER.debug("Found filter chain candidate filter '{}'", beanName);
+            shiroFilterFactoryBean.applyGlobalPropertiesIfNecessary(filter);
+            shiroFilterFactoryBean.getFilters().put(beanName, filter);
+        } else {
+            LOGGER.trace("Ignoring non-Filter bean '{}'", beanName);
+        }
+        return bean;
+    }
+
+    /**
+     * Does nothing - only exists to satisfy the BeanPostProcessor interface 
and immediately returns the
+     * {@code bean} argument.
+     */
+    @Override
+    public Object postProcessAfterInitialization(Object bean, String beanName) 
throws BeansException {
+        return bean;
+    }
+}
diff --git 
a/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroWebFilterConfiguration.java
 
b/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroWebFilterConfiguration.java
index 0ddcab131..fbe9e50f2 100644
--- 
a/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroWebFilterConfiguration.java
+++ 
b/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroWebFilterConfiguration.java
@@ -19,6 +19,7 @@
 package org.apache.shiro.spring.web.config;
 
 import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
+import org.apache.shiro.spring.web.ShiroFilterFactoryBeanPostProcessor;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
@@ -29,13 +30,17 @@ import java.util.List;
  */
 @Configuration
 public class ShiroWebFilterConfiguration extends 
AbstractShiroWebFilterConfiguration {
-
     @Bean
     @Override
     protected ShiroFilterFactoryBean shiroFilterFactoryBean() {
         return super.shiroFilterFactoryBean();
     }
 
+    @Bean
+    static ShiroFilterFactoryBeanPostProcessor 
shiroFilterFactoryBeanPostProcessor(ShiroFilterFactoryBean factory) {
+        return new ShiroFilterFactoryBeanPostProcessor(factory);
+    }
+
     @Bean(name = "globalFilters")
     protected List<String> globalFilters() {
         return super.globalFilters();
diff --git 
a/support/spring/src/test/resources/org/apache/shiro/spring/web/ShiroFilterFactoryBeanTest.xml
 
b/support/spring/src/test/resources/org/apache/shiro/spring/web/ShiroFilterFactoryBeanTest.xml
index 177784591..f91a11a70 100644
--- 
a/support/spring/src/test/resources/org/apache/shiro/spring/web/ShiroFilterFactoryBeanTest.xml
+++ 
b/support/spring/src/test/resources/org/apache/shiro/spring/web/ShiroFilterFactoryBeanTest.xml
@@ -51,5 +51,8 @@
         </property>
 
     </bean>
+    <bean id="shiroFilterFactoryBeanPostProcessor" 
class="org.apache.shiro.spring.web.ShiroFilterFactoryBeanPostProcessor">
+        <constructor-arg ref="&amp;shiroFilter"/>
+    </bean>
 
 </beans>

Reply via email to