学记:spring boot整合shiro出现UnavailableSecurityManagerException

  spring boot自带spring security,spring security自然不用说是一个强大的安全框架,但是用惯了shiro,一时半会用不来spring security,所以要在spring boot中自己整合shiro。说到整合shiro,网上也是有不少教程的,但是网上的教程也不是一定是对的,可能有版本等各种问题,所以说还是要自己来动手做一遍。

  在我动手整合的时候出现UnavailableSecurityManagerException的错误:

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.

spring整合shiro出现UnavailableSecurityManagerException在网上查出的问题都是没有配置DelegatingFilterProxy或者DelegatingFilterProxy的配置顺序错了,对应的解决办法就是在web.xml上添加DelegatingFilterProxy。

<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>

可是我们现在使用的spring boot啊,才不要再用回web.xml的配置文件呢。那到底怎么解决呢?

我第一想法就是,使用FilterRegistrationBean注册一个DelegatingFilterProxy:

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

跟上面一样,应该没问题吧?可这都是我的一厢情愿,出错了:

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]

看到下面这个错误行:

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

看到下面代码,我们大概可以知道,根据getTargetBeanName()来进行委派,而TargetBeanName是delegatingFilterProxy。

诶,不对啊,我shiroFilter的beanName不是这个啊,明明是shiroFilter。

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

解决办法

经过上面一大串推论,解决办法就是:

@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;
}

没有写太多shiro的整合代码,只写了解决UnavailableSecurityManagerException问题的关键代码,如需要可以自行网上查找。

时间: 2024-10-04 22:46:04

学记:spring boot整合shiro出现UnavailableSecurityManagerException的相关文章

Spring Boot 整合 Shiro ,两种方式全总结!

在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 今天松哥就来和大家聊聊 Spring Boot 整合 Shiro 的话题! 一般来说,Spring Security 和 Shiro 的比较如下: Spring Security 是一个重量级的安全管理框架:Shiro 则是一个轻量级的安全管理框架 Spring Security 概念复杂,配置繁琐:Shiro 概念简单.配置简单 Spring

上手spring boot项目(二)之spring boot整合shiro安全框架

题记:在学习了springboot和thymeleaf之后,想完成一个项目练练手,于是使用springboot+mybatis和thymeleaf完成一个博客系统,在完成的过程中出现的一些问题,将这些问题记录下来,作为自己的学习心得.在这先感谢群主TyCoding的Tumo项目,虽然本人实在太菜了,好些地方看不懂,但还是使我受益匪浅. shiro作为一个小巧灵活的安全框架,在认证和授权方面简约但又不简单,十分容易上手使用.下面是整合shiro的具体流程. 1.添加依赖 1 <!--shiro和s

Spring Boot 整合 Shiro

一.简介 Shiro是Apache下一个开源的安全框架,提供了认证.授权.加密.会话管理,与 Spring Security 相比,Shiro 是一个轻量级框架,使用了比较简单易懂易于使用的授权方式. 1.Shiro特性 Authentication:身份认证/登录,验证用户是不是拥有相应的身份: Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限: Session Manager:会话管理,用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中: Cry

spring boot整合shiro

安全框架Shiro和Spring Security比较,本文主要围绕Shiro进行学习 一 Shiro 是一个强大而灵活的开源安全框架,能够清晰的处理认证 授权 管理会话以及,密码加密 01 .认证与授权相关概念 安全实体:  系统需要保护的具体对象数据 权限: 系统相关的功能操作,例如基本的CRUD Authentication:身份认证授权/登录,验证用户是否拥有相应的身份 Authorization:  授权,即权限的认证,认证某个已认证的用户是否拥有某个权限 Session  Manag

Spring Boot 整合 Shiro+Thymeleaf

1.导包 <!-- springboot 与 shiro 的集成--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.1</version> </dependency> <!-- thymeleaf 与 shiro 集成--> <

Spring boot整合shiro权限管理

apache shiro: https://shiro.apache.org/ Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码学和会话管理.使用Shiro的易于理解的API,您可以快速.轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序. shiro的三个核心组件: Subject, SecurityManager 和 Realms. Subject:即"当前操作用户".但是,在Shiro中,Subject这一概念并不仅仅指人,

Spring boot整合jsp

这几天在集中学习Spring boot+Shiro框架,因为之前view层用jsp比较多,所以想在spring boot中配置jsp,但是spring boot官方不推荐使用jsp,因为jsp相对于一些模板引擎,性能都比较低,官方推荐使用thymeleaf,但是Spring boot整合jsp的过程已经完成,在这里记录一下. 这篇博文是在LZ上篇文章spring boot+mybatis整合基础上写的,开发工具仍然是Intellij idea.这篇文章的重点是Intellij idea的设置,否

activeMQ入门+spring boot整合activeMQ

最近想要学习MOM(消息中间件:Message Oriented Middleware),就从比较基础的activeMQ学起,rabbitMQ.zeroMQ.rocketMQ.Kafka等后续再去学习. 上面说activeMQ是一种消息中间件,可是为什么要使用activeMQ? 在没有使用JMS的时候,很多应用会出现同步通信(客户端发起请求后需要等待服务端返回结果才能继续执行).客户端服务端耦合.单一点对点(P2P)通信的问题,JMS可以通过面向消息中间件的方式很好的解决了上面的问题. JMS规

spring boot 整合 quartz 集群环境 实现 动态定时任务配置【原】

最近做了一个spring boot 整合 quartz  实现 动态定时任务配置,在集群环境下运行的 任务.能够对定时任务,动态的进行增删改查,界面效果图如下: 1. 在项目中引入jar 2. 将需要的表导入数据库 官网上有不同数据库的脚本,找到对应的,导入即可 3. java 代码 将quartz 的相关配置文件,配置为暴露bean,方便后期引用. 有一处关键的地方,就是注入spring 上下文,也可以算是一个坑.如果,不注入spring 上下文,那么新添加的定时任务job,是新new 的一个