关于Shiro登陆退出遇到的一些问题

    xiaoxiao2026-01-08  9

    写在开始

    最近项目中出现一些问题,以前可能不大关注,但是问题是实实在在存在的。

    问题一

    系统重启用户登陆或者退出报错:Disk Write of 407a1347-c2c6-434e-89e3-365aa277497c failed

    这个问题,并不是经常出现,看详细错误信息,应该是数据 list或者map序列化的问题。看了一下实体类都实现了序列化。

    解决方案

    突然想起,以前是没有这个问题的,自从升级了Ehcache的jar包,这个问题时常出现。目前使用的是ehcache2.10.0,随后版本降级为ehcache2.6.9,重启以后再没出现过这个问题。

    问题二

    用户退出无法请求到logout.action,导致尽管session已经清理,但是用户缓存信息还是实实在在存在的。

    如果把logout 改为user或者anon,会报以下错误:

    java.lang.IllegalStateException: org.apache.shiro.session.UnknownSessionException: There is no session with id [1370262d-eeac-4ee7-a86e-1a2b14c86d83]

    字面意思是,找不到session,的确F12 sid已经不见了,shiro在做跳转的时候就报这个错误(目前不清楚原因,但是后面有解决方案)

    部分代码:

    <!-- Shiro权限过滤过滤器定义 --> <property name="filterChainDefinitions"> <value> /common/** = anon /template/** = anon /LoginAction_login.action = anon /LoginAction_logout.action = logout /** =user </value> </property>

    仔细膜拜一下源代码,退出操作是走LogoutFilter过滤的。部分代码:

    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception { Subject subject = getSubject(request, response); String redirectUrl = getRedirectUrl(request, response, subject); try { subject.logout(); } catch (SessionException ise) { log.debug( "Encountered session exception during logout. This can generally safely be ignored.", ise); } issueRedirect(request, response, redirectUrl); return false; }

    注意:最后的return false,返回false表示不执行后续的过滤器,直接返回跳转到登录页面。所以也就不可能再请求到LoginAction_logout.action,也就不会清空用户缓存信息了。

    解决方案

    重写LogoutFilter:

    import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.apache.shiro.session.SessionException; import org.apache.shiro.subject.Subject; import org.apache.shiro.web.filter.authc.LogoutFilter; import com.acts.web.sys.utils.UserUtils; /** * 重写退出过滤器 * 创建者 张志朋 * 创建时间 2017年4月24日 */ public class SystemLogoutFilter extends LogoutFilter { @Override protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception { Subject subject = getSubject(request, response); String redirectUrl = getRedirectUrl(request, response, subject); try { //清空缓存 UserUtils.clearCache(); subject.logout(); } catch (SessionException e) { e.printStackTrace(); } issueRedirect(request, response, redirectUrl); return false; } }

    配置文件定义:

    <bean id="logout" class="com.acts.web.filter.SystemLogoutFilter"/> <!-- 加入filters --> <property name="filters"> <map> <entry key="logout" value-ref="kickoutSessionControlFilter"/> </map> </property>

    如果存在多realm,可能会返回不同的登陆页,这里可以把return false 改为 return true 执行后续的过滤器,自定义Action重定向不同的页面。

    好,到这两个问题都解决了。第二个问题,基本就是由于未理解shiro的原理导致的,所以大家使用开源框架的时候一定要弄清楚其原理,这样才可以精确的定位问题。

    小站:http://blog.52itstyle.com

    最新回复(0)