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

Shiro登出后跳转登录页失败,报UnknownSessionException求助

Shiro登出后跳转登录页抛出UnknownSessionException的解决方案

我之前也碰到过一模一样的坑!咱们先把问题拆解清楚,再一步步解决:

问题根源分析

从你贴的异常堆栈能明确看到:

org.apache.shiro.session.UnknownSessionException: There is no session with id [e6af7582-badd-4c0d-a296-12ebee91f8e5]

问题出在Spring的SessionFlashMapManager——当你调用SecurityUtils.getSubject().logout()后,Shiro已经彻底销毁了当前会话,但Spring在处理redirect:/login跳转时,会自动尝试从Session中读取FlashMap数据(用来传递跨请求的临时参数),这时候访问已销毁的Session就触发了异常。

可行解决方案

方案1:用原生Servlet跳转绕过FlashMap处理(最直接)

放弃Spring的ModelAndView跳转,改用Servlet原生的sendRedirect,同时手动清空Session,彻底避免Spring触发FlashMap的检索逻辑:

// 执行Shiro登出
SecurityUtils.getSubject().logout();
// 手动销毁当前请求绑定的Session
request.getSession().invalidate();
// 原生跳转至登录页
response.sendRedirect("/login");
// 返回null,告诉Spring不需要再处理视图
return null;

方案2:自定义FlashMapManager捕获异常

如果你必须保留ModelAndView的跳转方式,可以自定义一个安全的FlashMapManager,重写retrieveFlashMaps方法,捕获会话不存在的异常:

import org.apache.shiro.session.UnknownSessionException;
import org.springframework.web.servlet.support.SessionFlashMapManager;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.List;

public class SafeSessionFlashMapManager extends SessionFlashMapManager {
    @Override
    protected List<FlashMap> retrieveFlashMaps(HttpServletRequest request) {
        try {
            // 正常情况调用父类方法
            return super.retrieveFlashMaps(request);
        } catch (UnknownSessionException e) {
            // 会话已销毁时,返回空列表即可
            return Collections.emptyList();
        }
    }
}

然后在Spring的XML配置中替换默认的FlashMapManager:

<!-- 自定义安全FlashMapManager -->
<bean id="safeFlashMapManager" class="com.yourpackage.SafeSessionFlashMapManager"/>

<!-- 配置RequestMappingHandlerAdapter使用自定义的FlashMapManager -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="flashMapManager" ref="safeFlashMapManager"/>
</bean>

方案3:检查URL重写过滤器的执行顺序

从堆栈能看到你的UrlRewritFilter在Shiro过滤器之后执行了forward操作,如果这个过滤器里有访问Session的逻辑,也可能触发异常。可以调整web.xml中过滤器的顺序,让Shiro过滤器在UrlRewritFilter之后执行,确保重写逻辑在会话销毁前完成。

总结

最快速的解决方式是方案1,直接用原生跳转绕过Spring的FlashMap机制;如果项目依赖FlashMap传递参数,方案2是更合适的长期解决方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:22:50