Shiro 报错 No SecurityManager accessible(汇总)

本文汇总了Shiro在运行时出现'No SecurityManager accessible'错误的三种常见情况及其解决方法,从配置问题到代码实现,逐一解析,帮助读者理解和修复这个问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >




在写这篇文章之前,想了好长时间的题目该写什么,最后考虑到写这篇文章的目的,也就没有再起什么花哨的主题,而是找了这么一个简单粗暴有效的题目,方便有同样问题的童鞋们搜索。


背景


一如往昔,在谈这个问题之前,首先说说问题的背景所在。这个问题是前几天遇到的事,最近设计部给提了不少需求,于是一直在忙着实现这些需求,前几天说要发版,让提供一个新包供测试部进行全面的测试,其实,平常测试部也都在一直测着。发了新包之后,测试部给提了个 bug,可恨的是,这个 bug 在我本地却重现不了,因为我本地是没有这个问题的。当然,就是题目上说的错误了。


正文


在拿到这个问题之后,由于我本地的环境重现不了,而部署到 Linux 服务器上就会出现这个问题,这个让我比较郁闷,刚开始以为是环境的问题,后来发现不是。在网上查了查解决方案,怎么说的都有,但大都跟我这种情况不一样。我汇总了一下,大概有这几种情况。

第一种

### 解决 Shiro 中 `UnavailableSecurityManagerException` 异常 当遇到 `No SecurityManager accessible to the calling code` 的异常时,通常是因为应用程序未能正确初始化或配置 `SecurityManager`。为了有效解决此问题,可以采取以下措施: #### 1. 配置 Spring Boot 应用程序中的 Shiro Bean 确保在 Spring Boot 应用程序上下文中定义并注册了 `SecurityManager` bean。这可以通过创建一个配置类来实现,在该类中标记为 `@Configuration` 并提供相应的bean定义。 ```java import org.apache.shiro.mgt.DefaultSecurityManager; import org.apache.shiro.realm.text.IniRealm; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ShiroConfig { @Bean public DefaultSecurityManager securityManager() { DefaultSecurityManager manager = new DefaultSecurityManager(); manager.setRealm(new IniRealm("classpath:shiro.ini")); return manager; } } ``` 上述代码片段展示了如何声明一个 `DefaultSecurityManager` 实例,并将其关联到具体的 Realm 上下文[^1]。 #### 2. 初始化静态 Singleton SecurityManager 如果应用依赖于静态访问方式,则需保证 `SecurityUtils.setSecurityManager()` 方法被调用来设置全局唯一的 `SecurityManager` 实例。可以在启动阶段完成这项工作,比如在一个监听器或者事件处理器内执行。 ```java import org.apache.shiro.SecurityUtils; import org.apache.shiro.mgt.DefaultSecurityManager; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Component; @Component public class ShiroInitializer implements InitializingBean { private final DefaultSecurityManager securityManager; public ShiroInitializer(DefaultSecurityManager securityManager) { this.securityManager = securityManager; } @Override public void afterPropertiesSet() throws Exception { SecurityUtils.setSecurityManager(securityManager); } } ``` 这段代码说明了怎样利用 Spring 生命周期接口 `InitializingBean` 来确保 `SecurityManager` 被及时注入给 `SecurityUtils` 工具类。 #### 3. 检查线程绑定机制 有时即使已经设置了静态的 `SecurityManager` 单例实例,但在某些情况下仍然会抛出同样的异常。此时应考虑是否存在多线程环境下的竞争条件,即不同线程之间共享同一个 `Subject` 或者未正确传播当前用户的认证状态。对于这种情况,建议启用Shiro自带的支持自动管理ThreadLocal变量的功能。 ```properties # application.properties 文件中添加如下配置项 shiro.subjectDAO.sessionStorageEvaluator.cacheName=shiro-activeSessionsCache shiro.subjectDAO.principalCollectionSerializer.class=com.example.MyPrincipalCollectionSerializer ``` 以上属性可以帮助改善跨请求间的安全主体信息传递效率以及减少潜在的竞争风险[^2]。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值