You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shiro执行clearCachedAuthenticationInfo时缓存未清致会话无法清除,求解决方案

解决Shiro执行clearCachedAuthenticationInfo时缓存为null导致会话无法清除的问题

我之前也踩过这个Shiro缓存的坑!从你贴的代码来看,核心问题是getAvailableAuthenticationCache()返回了null,导致后续清除认证缓存的逻辑完全没执行,最终造成会话无法正常清除。下面我给你几个针对性的解决方案:

1. 确认Realm已正确开启认证缓存

Shiro的认证缓存默认是关闭的,必须手动开启才能让getAvailableAuthenticationCache()返回有效缓存实例:

Java配置方式

@Bean
public CustomShiroRealm customShiroRealm() {
    CustomShiroRealm realm = new CustomShiroRealm();
    // 开启认证缓存
    realm.setAuthenticationCachingEnabled(true);
    // 指定缓存名称(需和缓存管理器中的配置对应)
    realm.setAuthenticationCacheName("authenticationCache");
    return realm;
}

XML配置方式

<bean id="customShiroRealm" class="com.yourpackage.CustomShiroRealm">
    <!-- 开启认证缓存 -->
    <property name="authenticationCachingEnabled" value="true"/>
    <!-- 指定缓存名称 -->
    <property name="authenticationCacheName" value="authenticationCache"/>
</bean>

2. 确保缓存管理器已正确配置并关联到SecurityManager

如果没有给SecurityManager配置缓存管理器,Realm的缓存也无法正常初始化:

以Ehcache为例的Java配置

// 配置缓存管理器
@Bean
public CacheManager shiroCacheManager() {
    EhCacheManager cacheManager = new EhCacheManager();
    // 加载ehcache配置文件
    cacheManager.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");
    return cacheManager;
}

// 配置SecurityManager并关联缓存管理器和Realm
@Bean
public SecurityManager securityManager(CustomShiroRealm customShiroRealm, CacheManager shiroCacheManager) {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    securityManager.setRealm(customShiroRealm);
    securityManager.setCacheManager(shiroCacheManager);
    return securityManager;
}

同时要在ehcache-shiro.xml中定义对应的缓存:

<cache name="authenticationCache"
       maxEntriesLocalHeap="1000"
       eternal="false"
       timeToIdleSeconds="3600"
       timeToLiveSeconds="7200"
       overflowToDisk="false"/>

3. 添加兜底逻辑,避免缓存为null时失效

如果配置没问题但偶尔还是出现缓存为null的情况,可以在清除逻辑中添加兜底处理,直接操作会话:

protected void clearCachedAuthenticationInfo(PrincipalCollection principals) {
    if (!CollectionUtils.isEmpty(principals)) {
        Cache<Object, AuthenticationInfo> cache = this.getAvailableAuthenticationCache();
        if (cache != null) {
            Object key = this.getAuthenticationCacheKey(principals);
            cache.remove(key);
        } else {
            // 兜底:直接清除会话中的认证标记并终止会话
            Subject currentSubject = SecurityUtils.getSubject();
            Session session = currentSubject.getSession(false);
            if (session != null) {
                // 移除认证状态标记
                session.removeAttribute("org.apache.shiro.subject.support.DefaultSubjectContext_AUTHENTICATED_SESSION_KEY");
                // 终止会话
                session.stop();
            }
            // 同时清除当前Subject的认证状态
            currentSubject.logout();
        }
    }
}

4. 检查PrincipalCollection的有效性

确保传入的principals包含有效的用户身份信息,比如用户ID、用户名等。如果会话已过期或principals为空,不仅缓存key生成会有问题,后续逻辑也无法正常执行。

内容的提问来源于stack exchange,提问作者licoycn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:20:49