How to Register Custom Filter When Using Shiro Spring Boot

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

How to Register Custom Filter When Using Shiro Spring Boot

Rui Tang
I'm using shiro-spring-boot package, and I want to use my own filter
instead of the default filters.

For example, I have a TestFilter which extends from AccessControlFilter,
and I want to register this filter as name "test" and use the "test" name
when defining filter chain.

But I've tried a lot of ways to register this filter but without accessed,
please give me some tips.

Thank you!
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to Register Custom Filter When Using Shiro Spring Boot

Brian Demers
Any filter you create should be available by name.
https://shiro.apache.org/static/current/apidocs/org/apache/shiro/spring/web/ShiroFilterFactoryBean.html

something like this should work:

@Bean
public Filter test() {
    return new MyFilter();
}

On Wed, Apr 26, 2017 at 12:00 PM, Rui Tang <[hidden email]> wrote:

> I'm using shiro-spring-boot package, and I want to use my own filter
> instead of the default filters.
>
> For example, I have a TestFilter which extends from AccessControlFilter,
> and I want to register this filter as name "test" and use the "test" name
> when defining filter chain.
>
> But I've tried a lot of ways to register this filter but without accessed,
> please give me some tips.
>
> Thank you!
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to Register Custom Filter When Using Shiro Spring Boot

Rui Tang
Here my ShiroConfig.java file:

@Configuration
public class ShiroConfig {

  @Bean
  public PasswordService passwordService() {
    return new HmacSha1PasswordService();
  }

  @Bean
  public PasswordMatcher passwordMatcher(PasswordService passwordService) {
    PasswordMatcher passwordMatcher = new PasswordMatcher();
    passwordMatcher.setPasswordService(passwordService);
    return passwordMatcher;
  }

  @Bean
  @Qualifier("countly")
  @Primary
  public Realm countlyRealm(PasswordMatcher passwordMatcher) {
    CountlyRealm realm = new CountlyRealm();
    realm.setCredentialsMatcher(passwordMatcher);
    return realm;
  }

  @Bean
  @Qualifier("mock")
  public Realm mockRealm() {
    return new MockRealm();
  }

  @Bean
  public DefaultWebSecurityManager securityManager(Realm realm) {
    DefaultWebSecurityManager securityManager = new
DefaultWebSecurityManager();
    securityManager.setRealm(realm);
    return securityManager;
  }

  @Bean(name = "test")
  public TestFilter testFilter() {
    return new TestFilter();
  }

  @Bean
  public ShiroFilterChainDefinition shiroFilterChainDefinition() {
    DefaultShiroFilterChainDefinition
        shiroFilterChainDefinition =
        new DefaultShiroFilterChainDefinition();
    shiroFilterChainDefinition.addPathDefinition("/api/**", "test");
    return shiroFilterChainDefinition;
  }
 }

When starting using `mvn spring-boot:run` I get the following exception:

Caused by: java.lang.IllegalArgumentException: There is no filter with name
'test' to apply to chain [/api/**] in the pool of available Filters.
Ensure a filter with that name/path has first been registered with the
addFilter method(s).



On Thu, Apr 27, 2017 at 12:45 AM Brian Demers <[hidden email]>
wrote:

> Any filter you create should be available by name.
>
> https://shiro.apache.org/static/current/apidocs/org/apache/shiro/spring/web/ShiroFilterFactoryBean.html
>
> something like this should work:
>
> @Bean
> public Filter test() {
>     return new MyFilter();
> }
>
> On Wed, Apr 26, 2017 at 12:00 PM, Rui Tang <[hidden email]> wrote:
>
> > I'm using shiro-spring-boot package, and I want to use my own filter
> > instead of the default filters.
> >
> > For example, I have a TestFilter which extends from AccessControlFilter,
> > and I want to register this filter as name "test" and use the "test" name
> > when defining filter chain.
> >
> > But I've tried a lot of ways to register this filter but without
> accessed,
> > please give me some tips.
> >
> > Thank you!
> >
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to Register Custom Filter When Using Shiro Spring Boot

Brian Demers
Do you have an example project we can look at?

On Wed, Apr 26, 2017 at 9:06 PM, Rui Tang <[hidden email]> wrote:

> Here my ShiroConfig.java file:
>
> @Configuration
> public class ShiroConfig {
>
>   @Bean
>   public PasswordService passwordService() {
>     return new HmacSha1PasswordService();
>   }
>
>   @Bean
>   public PasswordMatcher passwordMatcher(PasswordService passwordService)
> {
>     PasswordMatcher passwordMatcher = new PasswordMatcher();
>     passwordMatcher.setPasswordService(passwordService);
>     return passwordMatcher;
>   }
>
>   @Bean
>   @Qualifier("countly")
>   @Primary
>   public Realm countlyRealm(PasswordMatcher passwordMatcher) {
>     CountlyRealm realm = new CountlyRealm();
>     realm.setCredentialsMatcher(passwordMatcher);
>     return realm;
>   }
>
>   @Bean
>   @Qualifier("mock")
>   public Realm mockRealm() {
>     return new MockRealm();
>   }
>
>   @Bean
>   public DefaultWebSecurityManager securityManager(Realm realm) {
>     DefaultWebSecurityManager securityManager = new
> DefaultWebSecurityManager();
>     securityManager.setRealm(realm);
>     return securityManager;
>   }
>
>   @Bean(name = "test")
>   public TestFilter testFilter() {
>     return new TestFilter();
>   }
>
>   @Bean
>   public ShiroFilterChainDefinition shiroFilterChainDefinition() {
>     DefaultShiroFilterChainDefinition
>         shiroFilterChainDefinition =
>         new DefaultShiroFilterChainDefinition();
>     shiroFilterChainDefinition.addPathDefinition("/api/**", "test");
>     return shiroFilterChainDefinition;
>   }
>  }
>
> When starting using `mvn spring-boot:run` I get the following exception:
>
> Caused by: java.lang.IllegalArgumentException: There is no filter with
> name
> 'test' to apply to chain [/api/**] in the pool of available Filters.
> Ensure a filter with that name/path has first been registered with the
> addFilter method(s).
>
>
>
> On Thu, Apr 27, 2017 at 12:45 AM Brian Demers <[hidden email]>
> wrote:
>
> > Any filter you create should be available by name.
> >
> > https://shiro.apache.org/static/current/apidocs/org/
> apache/shiro/spring/web/ShiroFilterFactoryBean.html
> >
> > something like this should work:
> >
> > @Bean
> > public Filter test() {
> >     return new MyFilter();
> > }
> >
> > On Wed, Apr 26, 2017 at 12:00 PM, Rui Tang <[hidden email]> wrote:
> >
> > > I'm using shiro-spring-boot package, and I want to use my own filter
> > > instead of the default filters.
> > >
> > > For example, I have a TestFilter which extends from
> AccessControlFilter,
> > > and I want to register this filter as name "test" and use the "test"
> name
> > > when defining filter chain.
> > >
> > > But I've tried a lot of ways to register this filter but without
> > accessed,
> > > please give me some tips.
> > >
> > > Thank you!
> > >
> >
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to Register Custom Filter When Using Shiro Spring Boot

Rui Tang
I've uploaded a simple demo to reproduce the problem. Just unzip it and run `mvn spring-boot:run` and exception will be thrown.

This application has no meaning, just for demo.

In `ShiroConfig.java` I've commented out a method to declare my own ShiroFilterFactoryBean. If uncomment this method and remove the `testFilter()` method and the application will work.

After digging into the code, I've got some idea about this problem.

When spring boot starts, the auto configuration will firstly run `org.apache.shiro.spring.config.web.autoconfigure.ShiroWebFilterConfiguration.filterShiroFilterRegistrationBean()` method, in this method, `shiroFilterFactoryBean()` will be called. `shiroFilterFactoryBean()` method just call `AbstractShiroWebFilterConfiguration.shiroFilterFactoryBean()`. In this method a ShiroFilterFactoryBean will be created.

In `ShiroFilterFactoryBean` class, there're two methods `createInstance()` and `postProcessBeforeInitialization()`. The `postProcessBeforeInitialization()` seems to register the @Bean filters to this class, then `createInstance()` uses there filters to create filter chain manager. But according to the problem, the `postProcessBeforeInitialization()` may not executed, then the named filter may not be injected so the startup failed.

If I use my own logic of creating the ShiroFilterFactoryBean then firstly add named filters then declare filter chain mapping then the application will work.

On Thu, May 4, 2017 at 11:03 PM Brian Demers <[hidden email]> wrote:
Do you have an example project we can look at?

On Wed, Apr 26, 2017 at 9:06 PM, Rui Tang <[hidden email]> wrote:

> Here my ShiroConfig.java file:
>
> @Configuration
> public class ShiroConfig {
>
>   @Bean
>   public PasswordService passwordService() {
>     return new HmacSha1PasswordService();
>   }
>
>   @Bean
>   public PasswordMatcher passwordMatcher(PasswordService passwordService)
> {
>     PasswordMatcher passwordMatcher = new PasswordMatcher();
>     passwordMatcher.setPasswordService(passwordService);
>     return passwordMatcher;
>   }
>
>   @Bean
>   @Qualifier("countly")
>   @Primary
>   public Realm countlyRealm(PasswordMatcher passwordMatcher) {
>     CountlyRealm realm = new CountlyRealm();
>     realm.setCredentialsMatcher(passwordMatcher);
>     return realm;
>   }
>
>   @Bean
>   @Qualifier("mock")
>   public Realm mockRealm() {
>     return new MockRealm();
>   }
>
>   @Bean
>   public DefaultWebSecurityManager securityManager(Realm realm) {
>     DefaultWebSecurityManager securityManager = new
> DefaultWebSecurityManager();
>     securityManager.setRealm(realm);
>     return securityManager;
>   }
>
>   @Bean(name = "test")
>   public TestFilter testFilter() {
>     return new TestFilter();
>   }
>
>   @Bean
>   public ShiroFilterChainDefinition shiroFilterChainDefinition() {
>     DefaultShiroFilterChainDefinition
>         shiroFilterChainDefinition =
>         new DefaultShiroFilterChainDefinition();
>     shiroFilterChainDefinition.addPathDefinition("/api/**", "test");
>     return shiroFilterChainDefinition;
>   }
>  }
>
> When starting using `mvn spring-boot:run` I get the following exception:
>
> Caused by: java.lang.IllegalArgumentException: There is no filter with
> name
> 'test' to apply to chain [/api/**] in the pool of available Filters.
> Ensure a filter with that name/path has first been registered with the
> addFilter method(s).
>
>
>
> On Thu, Apr 27, 2017 at 12:45 AM Brian Demers <[hidden email]>
> wrote:
>
> > Any filter you create should be available by name.
> >
> > https://shiro.apache.org/static/current/apidocs/org/
> apache/shiro/spring/web/ShiroFilterFactoryBean.html
> >
> > something like this should work:
> >
> > @Bean
> > public Filter test() {
> >     return new MyFilter();
> > }
> >
> > On Wed, Apr 26, 2017 at 12:00 PM, Rui Tang <[hidden email]> wrote:
> >
> > > I'm using shiro-spring-boot package, and I want to use my own filter
> > > instead of the default filters.
> > >
> > > For example, I have a TestFilter which extends from
> AccessControlFilter,
> > > and I want to register this filter as name "test" and use the "test"
> name
> > > when defining filter chain.
> > >
> > > But I've tried a lot of ways to register this filter but without
> > accessed,
> > > please give me some tips.
> > >
> > > Thank you!
> > >
> >
>

shiro-spring-boot-demo.zip (9K) Download Attachment
Loading...