异常信息:安全管理器没有实现 WebSecurityManager 接口。
The security manager does not implement the WebSecurityManager interface.
异常原因:Shiro 使用 ShiroFilter 来拦截需要安全控制的 URL,并通过 SecurityManager 实现认证、授权、会话管理、缓存管理等功能。Spring Boot 通过 ShiroFilterFactoryBean 生成 SpringShiroFilter 的实例时,需要传入实现 WebSecurityManager 接口的实现类,而非 SecurityManager 的实现类。因此只需要将 SecurityManager 的默认实现类 DefaultSecurityManager 改为 WebSecurityManager 的默认实现类 DefaultWebSecurityManager 即可。
@Bean
public DefaultSecurityManager getDefaultSecurityManager(Realm realm) {
// 创建安全管理器
// 改错:将其改为 DefaultWebSecurityManager 实例
// DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
DefaultSecurityManager securityManager = new DefaultSecurityManager(); // 注释
// ...
return securityManager;
}
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultSecurityManager securityManager) {
ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
// 设置安全管理器
filter.setSecurityManager(securityManager);
// ...
return filter;
}
小细节:ShiroFilterFactoryBean 工厂是通过 getObject 方法创建 AbstractShiroFilter( ShiroFilter 继承自 AbstractShiroFilter )。
public Object getObject() throws Exception {
if (instance == null) {
// 调用方法创建实例
instance = createInstance();
}
return instance;
}
protected AbstractShiroFilter createInstance() throws Exception {
// ...
SecurityManager securityManager = getSecurityManager();
if (securityManager == null) {
String msg = "SecurityManager property must be set.";
throw new BeanInitializationException(msg);
}
// 若安全管理器不是 WebSecurityManager 的实例, 则抛出异常!
if (!(securityManager instanceof WebSecurityManager)) {
String msg = "The security manager does not implement the WebSecurityManager interface.";
throw new BeanInitializationException(msg);
}
// ...
return new SpringShiroFilter((WebSecurityManager) securityManager, chainResolver);
}
参考文章:https://blog.csdn.net/longqiyuye925/article/details/108762340