一、报错
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.
二、原因
这个异常通常是表示 Apache Shiro
没有找到一个有效的 SecurityManager
实例,一般有以下两个含义:
-
没有绑定
SecurityManager
到ThreadContext
:Shiro
会在每个线程的ThreadContext
中维护一个SecurityManager
实例。如果在执行Shiro
操作时,当前线程的ThreadContext
中没有找到SecurityManager
,就会抛出这个异常。 -
没有作为静态单例存在:
Shiro
也支持将SecurityManager
作为一个全局的静态单例存在,通常在应用启动时初始化并一直存在。如果没有正确配置这个单例,也会导致无法访问SecurityManager
。
出现原因一般有:
-
未正确配置
SecurityManager
:Shiro
在启动时需要配置并初始化SecurityManager
,如果配置缺失或初始化失败,可能导致这个异常。例如,如果你没有在Shiro
配置文件或代码中指定SecurityManager
的实现,或者未正确初始化它,Shiro
就无法找到它。 -
Shiro
配置不正确:通常情况下,Shiro
会通过IniSecurityManagerFactory
或其他方式加载SecurityManager
配置。如果配置文件中没有正确配置SecurityManager
或者加载的配置文件路径不对,Shiro
也无法找到SecurityManager
。 -
多线程环境中
ThreadContext
没有绑定SecurityManager
:如果你的应用是多线程的,Shiro
需要在每个线程中都能够访问到SecurityManager
。如果没有正确设置,或者使用了线程池等技术,在某些线程中SecurityManager
可能没有正确绑定,导致此异常。
三、解决方案
原因【2. Shiro
配置不正确】需要检查配置文件,原因【1. 未正确配置 SecurityManager
】和原因【3. 多线程环境中 ThreadContext
没有绑定 SecurityManager
】可以通过以下代码配置:
@Configuration
public class ShiroConfig {
@Bean
public DefaultWebSecurityManager securityManager(MyShiroRealm myRealm) {
// 1. 配置 SecurityManager
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myRealm);
// 3. 多线程环境中 ThreadContext 绑定 SecurityManager
ThreadContext.bind(securityManager);
// 其他代码...
return securityManager;
}
// 其他代码...
}