UnavailableSecurityManagerException in Spring Boot integration shiro

Spring boot uses spring security by default. Spring security is a powerful security framework, needless to say. However, if you are used to shiro, you will not use spring security for a while, so you need to integrate shiro in spring boot. When it comes to integrating shiro, there are many online tutorials, but online tutorials are not necessarily right. There may be various problems such as version, so we should do it by ourselves.

The UnavailableSecurityManagerException error occurred when I started to consolidate:

2016-12-24 10:58:56.787 ERROR 7916 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton.  This is an invalid application configuration.] with root cause

org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton.  This is an invalid application configuration.

The problems found in the UnavailableSecurityManagerException of shiro during spring integration are that DelegatingFilterProxy is not configured or the configuration order of DelegatingFilterProxy is wrong. The corresponding solution is to web.xml Add DelegatingFilterProxy on.

<filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <async-supported>true</async-supported>
    <init-param>
             <param-name>targetFilterLifecycle</param-name>
             <param-value>true</param-value>
     </init-param>
</filter>
<filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
 </filter-mapping>

But now we use the spring boot. Don't use it again web.xml The configuration file of. How to solve it?

My first idea is to register a DelegatingFilterProxy using the FilterRegistrationBean:

@Bean
public FilterRegistrationBean delegatingFilterProxy(){
    FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
    DelegatingFilterProxy proxy = new DelegatingFilterProxy();
    proxy.setTargetFilterLifecycle(true);
    filterRegistrationBean.setFilter(proxy);
    return filterRegistrationBean;
}

It's the same as above, shouldn't it? But it's all my wishful thinking. I made a mistake:

org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'delegatingFilterProxy' is expected to be of type [javax.servlet.Filter] but was actually of type [org.springframework.boot.web.servlet.FilterRegistrationBean]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:378) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1082) ~[spring-context-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:326) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.initFilterBean(DelegatingFilterProxy.java:235) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:199) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:109) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4572) [tomcat-embed-core-8.5.5.jar:8.5.5]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5215) [tomcat-embed-core-8.5.5.jar:8.5.5]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.5.jar:8.5.5]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403) [tomcat-embed-core-8.5.5.jar:8.5.5]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393) [tomcat-embed-core-8.5.5.jar:8.5.5]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_25]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_25]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_25]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_25]
View Code

See the following error line:

at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:326) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]

Seeing the following code, we may know that the delegation is based on getTargetBeanName(), and TargetBeanName is delegatingFilterProxy.

Ah, no, the beanName of my shiroFilter is not this one. It is clearly shiroFilter.

protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
     Filter delegate = wac.getBean(getTargetBeanName(), Filter.class);
     if (isTargetFilterLifecycle()) {
         delegate.init(getFilterConfig());
     }
     return delegate;
}

terms of settlement

Through the above inference, the solution is as follows:

@Bean
public FilterRegistrationBean delegatingFilterProxy(){
    FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
    DelegatingFilterProxy proxy = new DelegatingFilterProxy();
    proxy.setTargetFilterLifecycle(true);
    proxy.setTargetBeanName("shiroFilter");
    filterRegistrationBean.setFilter(proxy);
    return filterRegistrationBean;
}

@Bean("shiroFilter")
public ShiroFilterFactoryBean shiroFilterFactoryBean() {
    ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
    .......
    return filterFactoryBean;
}

There are not too many integrated codes for shiro, but only the key codes to solve the UnavailableSecurityManagerException problem. If necessary, you can search online.

Tags: Java Spring Apache Shiro

Posted on Sun, 21 Jun 2020 02:28:31 -0400 by jollyjumper