acegi security实践教程—由debug调试来解析session

  在上一篇博客中《acegi security基于form表单认证-debug调试》中讲述了一个现象,每次重新打开新的浏览器,依然保留着上个页面。针对上个例子来说,要么是当前用户信息、要么是无权限信息。出现这个现象上篇博客我们已经分析过,就是securitycontext中已经存在认证过的权限对象。

  那么,我想,重新运行userinfo.jsp页面,重新认证一遍,怎么办啊?唯一的办法,stop server;open server again;不要这么笨吧。
  肯定有人会说,傻啊,运行login.jsp页面啊。这也是一个办法。但是遇到一个这样的情况:这个页面静止不操作半天,然后刷新这个页面时,作为程序员的你,觉得该如何处理呢?结果又该是怎样的呢?

  基于此条件下,我们给大家介绍一下httpSessionContextIntegrationFilter,这个session过滤器开篇已经介绍过了,但是在两个demo中一直没有用到。那我们今天就在acegi配置文件中添加这个fiter,记住这个sessionfilter是在各个filter之前的,acegi配置文件中的filter是有顺序要求的,想起来没?若没,请温习《acegi security入门》
  在form表单认证demo中,acegi配置文件中添加sessionfiter,其他一切都无需修改。
  
    <bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
            <property name ="filterInvocationDefinitionSource">
                 <value >
                     PATTERN_TYPE_APACHE_ANT
                     /**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
                 </value >
            </property >
     </bean >
     
     <bean id ="httpSessionContextIntegrationFilter"
          class="org.acegisecurity.context.HttpSessionContextIntegrationFilter" />  
 另外再温习一次,acegi控制流程:

  目的是:再打开一个会话浏览器或session过期后,应该跳转到登陆页面。
  添加sessionfitler后
  测试如下:
  1. 依然是运行http://localhost:8080/acegitest2/userinfo.jsp
  2. 第一次运行,出现登陆页面,使用test/1无权限用户登陆,展示无权限页面
  3. 不关闭此浏览器,再打开一个浏览器,再次运行http://localhost:8080/acegitest2/userinfo.jsp
  你的浏览器显示什么页面呢?
  是这样?
 
  还是这样?

  若是下图,则说明session是一样的。我们知道IE8中默认是session共享的。
  测试工具:上图是IE9。下图是IE8。
  4. 关闭此浏览器,再打开一个浏览器,再次运行http://localhost:8080/acegitest2/userinfo.jsp
  你的浏览器显示什么页面呢?
  你会发现IE8和IE9下,都会出现同一个页面即login.jsp。
  5. 思考?
  再次出现验证出现登陆页面,说明是不同的session。关闭浏览器后,为啥IE8、9,session就没有了呢。
  我们知道cookie是客户端存放的,session是服务器维持的,关闭浏览器,只是我客户端关闭,tomcat没有停止啊?难道服务器知道浏览器关闭?
  • session是什么?
   浏览器与服务器之间一系列交互动作称为一个session。

  • session存放在哪儿?
   session存放在服务器上,由服务器维持session。

  • session是谁创建的?
   session是在服务器上,当然是服务器创建的。

  • session何时创建的呢?是我们访问url地址时就创建的吗?
   很多人都以为我们一运行url,就自动生成了session。这是很多错误的观点。对于对于这种观点的人,也可以理解,因为开始我们不动手做或不涉及到session这块,是自然而然的生成这种观点,并且大多部分我们用框架或访问人家网站什么的,都会有记忆功能。

   实际上session通过java程序创建的:request.getSession(flag);getSession不是获得当前的session吗,怎么会是创建session呢?没有create啊?其实这是隐含创建的,我们解释一下这个方法,也许第一眼又误认为了。
   request.getSession(flag);为啥有个参数呢?你平时都带不带参数呢?带或不带,也许影响你的程序哦。
   当flag=false时,request.getSession(false)有则返回当前session,无则返回null。
   当flag=true时,request.getSession(true)有则返回当前session,无则创建一个session。
   而我们经常使用的 request.getSession();这个方法,到底等同以上那个呢?哈哈,不幸的是,它等同于参数为true的方法。在座的您,有没有中枪的哦?
   哈哈,明白了吧,为啥产生session了吧。

   肯定有人站起来反驳,我就新建一个helloworld.jsp,没有任何java程序,jsp中还可以输出session呢。在jsp中<% out.println(session.getId());%>,你如何解释这个现象啊--啊--啊。
   哈哈,这次你又被蒙在鼓里了。我们都知道jsp最后都编译成java程序,实际上jsp就是一个sevlet,那么servlet肯定优先于jsp页面。亲,你去看看jsp编译成java程序中有没有类似request.getSession();这句话。
   在tomcat_home/work/Catalina/localhost/org/你的项目/org/apache/jsp/你jsp目录中相应的java和class文件,尝试着打开一下,猛然会发现,我KAO,还真有这句话:session = pageContext.getSession();至于pageContext我就不解释啦。
   这下是否有一种被欺骗的赶脚啊。其实人家可是为咱们好。

   此时刚才的人又站起来了,再次疑惑,可jsp啥都没有,就一个<% out.println(session.getId());%>语句。
   其实jsp中默认情况会有:<%@page session="true"%>,若你jsp中显示改成:<%@page session="false"%>,那么光秃秃的jsp中session就会null啦。
   这下是否有一种更被欺骗的赶脚啊。其实人家确实为咱们好。

  • session何时灭呢?何时销毁?
   我们了解了session何时创建的了,那session何时销毁的?就刚才acegi框架测试demo,关闭浏览器后,session为null,导致重新验证,进入登陆页面。那意思是说关闭浏览器,session就销毁了?
   既然session创建是程序来决定的,其实session销毁,也是程序session.invalidate()来决定的。
   那关闭浏览器,session变为null,是因为调用session.invalidate()原因吗?这个不能颠倒顺序。若关闭浏览器调用session.invalidate()则session变为null。而反过来则不通。为啥大部分人会感觉关闭浏览器,session为null,关键acegidemo中的session也为null呢??
   那就得了解session的原理了。

  • session技术原理
   当浏览器访问服务器时,服务器首先判断客户端请求中是否包含session的标识,若存在,说明服务器已经给客户端开辟一个session空间,然后根据此标识查找具体的session;若不存在,则服务器给客户端新建一个session,然后把sessionId发给浏览器。
   其实session时利用cookie来保存sessionid,只不过在cookie中不是sessionid,而是jsessionid。只不过jsessionid就是sessionid的值。
   这样的话,cookie时存在浏览器生命周期,当浏览器关闭后,cookie就没有了,导致cookie中的jsessionid也就没有了。因此也无法找到服务器中的session了,不过session在服务器中还存在,只不过客户端再也无法找到而已。
   所以说呢,浏览器关闭,看似session销毁,是因为大部分session是基于cookie存放sessionid原理实现的.但是真正的session对象在server中没有被销毁,不销毁,一直占内存?

   正式由于浏览器关闭,session不能真正销毁,所以服务器端有一个session时间的机制.当服务端server检测到某一个session距它上次活跃期超过了规定的时间,那么服务器端就会调用session.invalidate()来销毁.tomcat默认配置时间是30分钟【tomcat6.0.37】当然这个时间可以自己修改,直接在自己项目中web.xml中进行配置即可。
   所以session销毁的情况如下:一是调用session.invalidate();二是session回话过期;三是server停止。

   那若客户端禁用了cookie呢?
   这就用到另外一个技术—URL重写。URL重写是在url地址后面加上jsessionid,有两种展示方式:一种是http://localhost:8080/项目名,jsessionid=***另一种是http://localhost:8080/项目名?jsessionid=***
   那具体如何实现呢?这就用到java提供的api了。respone.encodeURL("地址")和response.encodeRedirectURL
其中后者主要这么使用:response.sendRedirect(response.encodeRedirectURL)重定向应用。这两个方法可以判断,若客户端禁止cookie,然后就会在url地址后面添加jsessionid;若客户端支持cookie,则就是原来的url地址。

   对于session了解后,下篇博客讲到系统常用注销功能时就会很简单了。大家对这块可以尝试自己测试下,有啥发现或见解,及时沟通交流。


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值