Shiro在shiro logout 处理退出后,怎么防止浏览器的后退刷新操作

6232人阅读
Shiro(49)
退出操作可以通过调用subject.logout()来释放你的登录信息,如:
currentUser.logout(); //removes all identifying information and invalidates their session too.&
当你调用logout,任何现有的Session 都将会失效,而且任何身份都将会失去关联(例如,在Web 应用程序中,RememberMe cookie 也将被删除)。在Subject 注销后,该Subject 的实例被再次认为是匿名的。
由于在Web 应用程序记住身份往往是依靠Cookies,然而Cookies 只能在Response 被committed 之前被删除,所以强烈建议在调用subject.logout()后立即将终端用户重定向到一个新的视图或页面。这样能够保证任何与安全相关的Cookies都能像预期的一样被删除。这是HTTP cookies 的功能限制,而不是Shiro的问题。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:485476次
积分:6085
积分:6085
排名:第2287名
原创:119篇
转载:34篇
评论:104条
(1)(1)(1)(1)(7)(4)(3)(1)(2)(1)(4)(2)(3)(6)(9)(9)(10)(7)(9)(6)(4)(6)(6)(7)(6)(4)(3)(1)(1)(2)(1)(4)(1)(1)(1)(1)(1)(1)(1)(2)(1)(1)(1)(1)(1)(1)(1)(2)(3)(1)(4)登录之后,不能退出,logout后跳转首页,状态不改变 - 问答 - Yii Framework 中文社区
登录之后,不能退出,logout后跳转首页,状态不改变
悬赏 50 金钱
登录之后,不能退出,logout后跳转首页,状态不改变,还是处于登录状态,这是什么原因引起的,求大神解惑!
默认的,logout是要求post执行的~你确定是用post方法调用的logout吗?
'verbs' =& [
'class' =& VerbFilter::className(),
'actions' =& [
'logout' =& ['post'],
共 7 条回复是的,确定!
public function actionLogout()
var_dump(Yii::$app-&user-&logout());//改成这样试试看输出的是什么信息~
return $this-&goHome();
也可能不是这个原因,在我浏览器上,登录之后就不能退出了,但是在同事浏览器上可以正常的登录退出,浏览器缓存问题么,还是浏览器兼容?
可能是之前存在cookie或者session的问题
是的,默认的框架里退出按钮是这样的:&a href="index.php?r=site%2Flogout" data-method="post"&Logout (admin)&/a&
也是如果浏览器不支持data-method形式标签,就不行了~也就是会有兼容性问题~
兼容情况请参照以上链接~
不知道你用的神马浏览器捏。。。。很容易确认,用火狐试试看就知道是不是你浏览器问题了~
浏览器的名称为这个的_identity的cookie,清除了登录状态也就没有了,再次登录也可以正常的登录退出了
没有找到数据。
您需要登录后才可以回答。 |当前访客身份:游客 [
当前位置:
shiro 的部分配置如下:
&bean id=&securityManager& class=&org.apache.shiro.web.mgt.DefaultWebSecurityManager&&
&property name=&sessionMode& value=&native&/&
&property name=&cacheManager& ref=&cacheManager&/&
&property name=&sessionManager& ref=&sessionManager&/&
&property name=&realm& ref=&shiroDbRealm&/&
&bean id=&cacheManager& class=&org.apache.shiro.cache.ehcache.EhCacheManager&/&
&bean id=&sessionValidationScheduler& class=&org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler&&
&property name=&interval& value=&1800000&/&
&bean id=&sessionManager& class=&org.apache.shiro.web.session.mgt.DefaultWebSessionManager&&
&property name=&sessionDAO& ref=&sessionDAO&/&
&property name=&globalSessionTimeout& value=&3600000&/&
&property name=&sessionValidationScheduler& ref=&sessionValidationScheduler&/&
&property name=&sessionValidationSchedulerEnabled& value=&true&/&
&bean id=&shiroFilter& class=&org.apache.shiro.spring.web.ShiroFilterFactoryBean&&
&property name=&securityManager& ref=&securityManager&/&
&property name=&loginUrl& value=&/login&/&
&property name=&successUrl& value=&/system&/&
&property name=&unauthorizedUrl& value=&/login?unauthorized&/&
&property name=&filterChainDefinitions&&
/login = authc
用户登录后没有安全退出就直接关闭浏览器后,有两种可能:
1) 用户就是想退出,且没有在会话超时时间内再次登录。缓存中孤立会话在超时后,被一个定时任务清理掉。
2) 用户误关闭了浏览器。这种情况下,用户会再次登录。此时因为上次的会话还存在,所以不会去执行FormAuthenticationFilter,也就不会跳转到successUrl,而是会执行登录页面中form的post action。
我就想到了两种解决方法:
1) 显示登录页面的 get /login 方法里,判断会话,有就安全退出
@RequestMapping(value = &/login&, method = RequestMethod.GET)
public String loginInit() {
if (SecurityUtils.getSubject().getSession() != null) {
SecurityUtils.getSubject().logout();
return &login&;
2) 写在post /login 里。
不知道各位有没有更好的方法?
共有11个答案
<span class="a_vote_num" id="a_vote_num_
你的问题没有彻底理解清楚,第一浏览器与Session之间的关系没有理顺,所以你的方案没法彻底解决。给你分析一下
服务器Session与浏览器如何关联,浏览器打开时会请求服务器(当然不绝对会产生Session,请求html文件时可能不产生),浏览器会在cookie中存下来,每次请求服务器时会提交给服务器,这样服务求在根据cookie中的sessionId找到对应的Session。浏览器一旦关闭cookie会清除,在次打开没法找到原来的cookie,关联不起来咯。当然关闭浏览器tab标签没关系,只要浏览器没有关闭cookie就不会清除
而你的问题是用户没有点击退出Ehcache中没有清除,所以你写一个sessionFilter,获取session失效事件清除Ehcahe中的数据就可以了,至于想关闭浏览器在打开不需要登录那这能告诉你不太现实,实现起来需要哦在客户端处理不安全。
<span class="a_vote_num" id="a_vote_num_
谢谢你的回答。
服务器Session与浏览器如何关联,浏览器打开时会请求服务器(当然不绝对会产生Session,请求html文件时可能不产生),浏览器会在cookie中存下来,每次请求服务器时会提交给服务器,这样服务求在根据cookie中的sessionId找到对应的Session。浏览器一旦关闭cookie会清除,在次打开没法找到原来的cookie,关联不起来咯。当然关闭浏览器tab标签没关系,只要浏览器没有关闭cookie就不会清除
你说的没错。但是在我的shiro环境中,只要不是安全退出且会话没有过期,每次打开IE9,'JSESSIONID' cookie 的值都是同一个,所以会在Ehcache中找到缓存的会话。
另外,Chrome的话只要关闭就会清除'JSESSIONID' cookie。
而你的问题是用户没有点击退出Ehcache中没有清除,所以你写一个sessionFilter,获取session失效事件清除Ehcahe中的数据就可以了,至于想关闭浏览器在打开不需要登录那这能告诉你不太现实,实现起来需要哦在客户端处理不安全。
配置sessionValidationScheduler就是为了在会话超时后,自动清理缓存。
<span class="a_vote_num" id="a_vote_num_
我也遇到相同问题,求解决,登陆以后 要是我没有安全退出直接关闭浏览器, 由于认证&currentUser.isAuthenticated()是True,所以直接拷贝之前访问的页面仍然能够访问,而且我还遇到一个问题,当我访问首页的时候ip后面会有jsessionid
,然后重启服务器就会出现异常
org.apache.shiro.session.UnknownSessionException: There is no session with id [53e-4aee-b369-54e849c49ff3]
at org.apache.shiro.session.mgt.eis.AbstractSessionDAO.readSession(AbstractSessionDAO.java:170)
at org.apache.shiro.session.mgt.eis.CachingSessionDAO.readSession(CachingSessionDAO.java:261)
at org.apache.shiro.session.mgt.DefaultSessionManager.retrieveSessionFromDataSource(DefaultSessionManager.java:236)
at org.apache.shiro.session.mgt.DefaultSessionManager.retrieveSession(DefaultSessionManager.java:222)
at org.apache.shiro.session.mgt.AbstractValidatingSessionManager.doGetSession(AbstractValidatingSessionManager.java:118)
at org.apache.shiro.session.mgt.AbstractNativeSessionManager.lookupSession(AbstractNativeSessionManager.java:105)
at org.apache.shiro.session.mgt.AbstractNativeSessionManager.getSession(AbstractNativeSessionManager.java:97)
at org.apache.shiro.mgt.SessionsSecurityManager.getSession(SessionsSecurityManager.java:125)
at org.apache.shiro.mgt.DefaultSecurityManager.resolveContextSession(DefaultSecurityManager.java:456)
at org.apache.shiro.mgt.DefaultSecurityManager.resolveSession(DefaultSecurityManager.java:442)
at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:338)
at org.apache.shiro.subject.Subject$Builder.buildSubject(Subject.java:846)
at org.apache.shiro.web.subject.WebSubject$Builder.buildWebSubject(WebSubject.java:148)
at org.apache.shiro.web.servlet.AbstractShiroFilter.createSubject(AbstractShiroFilter.java:292)
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:359)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:877)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:594)
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1675)
at java.lang.Thread.run(Thread.java:662)
虽然对程序没什么影响,请高手解答!
--- 共有 3 条评论 ---
: 你的问题解决了吗?
(1年前)&nbsp&
我现在也遇到这个问题了,以前在IE下刷新下就OK了,现在系统都登录不进去了,新建会话也不行,求哪位高手再指点下。
(3年前)&nbsp&
是因为浏览器默认共享凭据造成的,虽然你关闭了这个浏览器窗口,如果还有其他的窗口存在,会话Cookie不会过期。
IE下的解决办法是:文件-》新建会话,来运行你的工程。
Chrome没有找到如何新建会话窗口。
(3年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
能不能把cache保存在session里面啊
<span class="a_vote_num" id="a_vote_num_
关闭浏览器,再打开后,虽然授权缓存了,但是认证是必须的,在认证成功后,清除之前的缓存,这样也是有效的,可以试试。
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException {
AuthenticationInfo info = super.doGetAuthenticationInfo(token);
clearCache(info.getPrincipals());
<span class="a_vote_num" id="a_vote_num_
朋友你可以把你的代码发给我嘛,我是初学者,
<span class="a_vote_num" id="a_vote_num_
引用来自“纯天然原味酱”的答案谢谢你的回答。
服务器Session与浏览器如何关联,浏览器打开时会请求服务器(当然不绝对会产生Session,请求html文件时可能不产生),浏览器会在cookie中存下来,每次请求服务器时会提交给服务器,这样服务求在根据cookie中的sessionId找到对应的Session。浏览器一旦关闭cookie会清除,在次打开没法找到原来的cookie,关联不起来咯。当然关闭浏览器tab标签没关系,只要浏览器没有关闭cookie就不会清除
你说的没错。但是在我的shiro环境中,只要不是安全退出且会话没有过期,每次打开IE9,'JSESSIONID' cookie 的值都是同一个,所以会在Ehcache中找到缓存的会话。
另外,Chrome的话只要关闭就会清除'JSESSIONID' cookie。
而你的问题是用户没有点击退出Ehcache中没有清除,所以你写一个sessionFilter,获取session失效事件清除Ehcahe中的数据就可以了,至于想关闭浏览器在打开不需要登录那这能告诉你不太现实,实现起来需要哦在客户端处理不安全。
配置sessionValidationScheduler就是为了在会话超时后,自动清理缓存。package com.shadow.shiro.extend.session.
import java.util.C
import java.util.I
import org.apache.log4j.L
import org.apache.shiro.cache.CacheM
import org.apache.shiro.session.ExpiredSessionE
import org.apache.shiro.session.InvalidSessionE
import org.apache.shiro.session.S
import org.apache.shiro.session.mgt.DefaultSessionK
import org.apache.shiro.session.mgt.SessionK
import org.apache.shiro.session.mgt.SimpleS
import org.apache.shiro.web.session.mgt.DefaultWebSessionM
import com.shadow.shiro.extend.session.WebSessionM
public class SimpleWebSessionManager extends DefaultWebSessionManager implements
WebSessionManager {
private CacheManager cacheM
private final static Logger logger = Logger
.getLogger(SimpleWebSessionManager.class);
public SimpleWebSessionManager() {
public void validateSessions() {
if (logger.isInfoEnabled())
(&Validating all active sessions...&);
int invalidCount = 0;
Collection&?& activeSessions = getActiveSessions();
if (activeSessions != null && !activeSessions.isEmpty()) {
for (Iterator&?& i$ = activeSessions.iterator(); i$.hasNext();) {
Session session = (Session) i$.next();
SessionKey key = new DefaultSessionKey(session.getId());
validate(session, key);
} catch (InvalidSessionException e) {
if (cacheManager != null) {
SimpleSession s = (SimpleSession)
if (s.getAttribute(SESSION_USER_KEY) != null)
cacheManager.getCache(null).remove(
s.getAttribute(SESSION_USER_KEY));
if (logger.isDebugEnabled()) {
boolean expired = e instanceof ExpiredSessionE
String msg = (new StringBuilder()).append(
&Invalidated session with id [&).append(
session.getId()).append(&]&).append(
expired ? & (expired)& : & (stopped)&)
.toString();
logger.debug(msg);
invalidCount++;
if (logger.isInfoEnabled()) {
String msg = &Finished session validation.&;
if (invalidCount & 0)
msg = (new StringBuilder()).append(msg).append(&
[&).append(
invalidCount).append(&] sessions were stopped.&)
.toString();
msg = (new StringBuilder()).append(msg).append(
No sessions were stopped.&).toString();
public void setCacheManager(CacheManager cacheManager) {
this.cacheManager = cacheM
这几天也在玩shiro,今天中午也遇到这样一个问题,上面是我的解决方案,继承原本的manager然后重载验证的那个方法
加入自己的cachemanager然后移除,网上的其他方法都是治标不治本,仅供参考本方案,刚来oschina报道,顺便露个脸,谢谢支持
<span class="a_vote_num" id="a_vote_num_
遇到同样的问题,请问怎么解决的。
<span class="a_vote_num" id="a_vote_num_
设置缓存有效期就行了,若想关闭浏览器就清空 SESSION 得写个基于网页的容器控件之类的,用来监控页面状态。
<span class="a_vote_num" id="a_vote_num_
sessionValidationScheduler.sessionManager
$sessionManager
更多开发者职位上
有什么技术问题吗?
纯天然原...的其它问题
类似的话题

我要回帖

更多关于 shiro logout 处理 的文章

 

随机推荐