JavaWeb高级编程(五)—— 使用会话来维持HTTP状态

一、需要会话的原因

       从服务器的角度来说,当请求结束时,客户端与服务器之间就再有任何联系,如果有下一个请求开始时,就无法将新的请求与之前的请求关联起来。这是因为 HTTP请求自身是完全无状态的,会话就是用来维持请求和请求之间的状态的。

        拿生活场景举例:你进入最喜欢的超市购物,找到一个购物车(从服务器获得会话),一边逛一边挑选喜爱的商品并将它们添加到购物车中(将商品添加到会话中),购物结束后将购物车中的商品取出并递给收银员,收银员扫描你购买的商品并接收你的付款(通过会话付款),付款结束后出门并还回购物车(关闭浏览器或注销,结束会话)。

二、使用会话cookie和URL重写

        会话是由服务器或Web应用程序管理的某些文件、内存片段、对象或者容器,它包含了分配给它的各种不同的数据。这些数据元素可以是用户名、购物车、工作流细节等,用户浏览器中不用保持或维持任何此类数据,它们只由服务器或Web应用程序代码管理。容器和用户浏览器之间将通过某种方式连接起来,因此通常会话会被赋予一个随机生成的字符串,称为会话ID。

        第一次创建会话时,服务器创建的会话ID将会作为响应的一部分返回到用户浏览器中,接下来从用户浏览器中发出的请求都将通过某种方式包含该会话ID,当应用程序收到含有会话ID的请求时,它可以通过该ID将会话与当前请求关联起来。剩下需要解决的问题就是如何将会话ID从服务器返回到浏览器中,并在之后的请求中包含该ID,目前有两种可用的技术:会话cookie和URL重写。

1、了解会话cookie

        cookie是一种必要的通信机制,可以通过Set-Cookie响应头在服务器和浏览器之间传递任意的数据,并存储在用户计算机中,然后再通过请求头Cookie从浏览器返回到服务器中。cookie可以有各种不同的特性,如下:

① Domain:告诉浏览器应该将cookie发送到哪个域名中;

② Path:进一步将cookie限制在相对于域的某个特定URL中,每次浏览器发出请求时,它都将找到匹配该域和路径的所有cookie;

③ Expires:与Max-age,HTTP/1.0会优先处理该指令,它定义了cookie的绝对过期日期,如果cookie已经过期,浏览器将会立即删除它;

④ Max-age:与Expires互斥,HTTP/1.1会优先处理该指令,它定义了cookie将在多少秒后过期,如果cookie中不含有Expires和Max-age,cookie将会浏览器关闭时被删除;

⑤ Secure:(不需要有值),浏览器将只会通过HTTP发送cookie,这将保护cookie,避免以未加密的方式进行传输;

⑥ HttpOnly:它把cookie限制在直接的浏览器请求中,使得JavaScript、Flash以及其他插件无法访问cookie。

注意:尽管HttpOnly将阻止JavaScript使用doucment.cookie属性来访问cookie,但由JavaScript创建的AJAX请求仍然会包含会话ID cookie,因为是浏览器负责AJAX请求头的生成而不是JavaScript,这意味着服务器仍然能够将AJAX请求关联到用户的会话。

        当Web服务器和应用服务器使用cookie在客户端存储会话ID时,这些ID将随着每次的请求被发送到服务器端,在JAVAEE应用服务器中,会话cookie的名字默认为JSESSIONID 

2、URL中的会话ID

        JavaEE服务器将会话ID添加到URL的最后一个路径段的矩阵参数中,通过这种方式分离开会话ID与查询字符串的参数,使它们不会互相冲突。

        请求URL只会在将会话ID从浏览器发送到服务器时有效,那么第一次如何将请求URL中的会话ID从服务器发送到浏览器呢?答案是必须将会话ID内嵌在应用程序返回的所有URL中,包括页面的链接、表单操作以及302重定向。

        HttpServletResponse接口定义了两个可以重写URL的方法:encodeURL和encodeRedirectURL,它们将在必要的时候将会话ID内嵌在URL中,任何在链接、表单操作或其他标签中的URL都将被传入到encodeURL方法中,然后该方法将会返回一个正确的、经过编码处理的URL(任何传入sendRedirect响应方法中的URL可以传入encodeRedirectURL方法中)。将JSESSIONID矩阵参数内嵌在URL的最后一个路径段中需要满足下面4个条件:

① 会话对于当前请求是活跃的(要么它通过传入会话ID的方式请求会话,要么应用程序创建了一个新的会话);

② JSEESSIONID cookie在请求中不存在;

③ URL不是绝对的URL,并且是同一Web应用程序中的URL;

④ 在部署描述符中已经启用了对会话URL重写的支持。

3、会话的漏洞

⑴ 复制并粘贴错误

        不知情的用户决定要跟朋友分享应用程序中的某个页面,并将地址栏中的URL复制粘贴出来,那么他的朋友将看到URL中包含的会话ID,如果他们在该会话终结之前访问该URL,那么他们也会被服务器当成之前分享URL的用户,这明显会引起问题。

        解决此问题的方法是:完全禁止在URL中内嵌会话ID。

⑵ 会话固定

        攻击者会首先找到允许在URL中内嵌会话ID的网站,然后获取一个会话ID,并将含有会话ID的URL发送给目标用户。此时,当用户点击链接进入网站时,他的会话ID就变成了URL中已经含有的会话ID(攻击者已经持有的会话ID),如果用户接着在该会话期间登录网站,那么攻击者也可以登录成功。

        解决这个问题的两种方法:一是同复制粘贴一样禁止在URL中内嵌会话ID,二是在登录后采用会话迁移,即当用户登录后,修改会话ID或者将之前的会话信息复制到一个新的会话中,并使之前的会话无效。

⑶ 跨站脚本和会话劫持

        攻击者将利用网站的漏洞实行跨站脚本攻击,将JavaScript注入到某个页面,通过document.cookie读取会话ID cookie中的内容,当攻击者从用户处获得会话ID后,他可以通过在自己的计算机中创建cookie来模拟该会话。

        解决这个问题的方法是:不要在网站中使用跨站脚本,并在所有的cookie中使用HttpOnly特性。

⑷ 不安全的cookie

        最后一个需要考虑的是中间人攻击(MitM攻击),这是典型的数据截获攻击,攻击者通过观察客户端和服务端的交互或响应,从中获取信息。

        解决这个问题的方法是:使用HTTPS来保护网络通信,cookie的secure标志将告诉浏览器只应该通过HTTPS传输cookie。

三、在会话中存储数据

1、在部署描述符中配置会话

        下面是一份详细的关于在部署描述符中配置会话的说明:

<!--下面标签中的标签选项都是可选的,如果选择了要按照一定的顺序添加-->
  <session-config>
    <!--会话的超时时间(单位:分钟),Tomcat默认30分钟,如果此值小于0将永远不会过期-->
    <session-timeout>30</session-timeout>
    <!--只有在追踪模式中使用了cookie时,才可以使用此标签-->
    <cookie-config>
      <!--默认值,不需要修改-->
      <name>JSESSIONID</name>
      <!--domain标签和path标签对应着cookie的Domain和Path特性,Web容器已经设置了正确的默认值,通常不需要修改它们-->
      <domain>example.org</domain>
      <path>/shop</path>
      <!--此标签内可以添加任意文本-->
      <comment>other info</comment>
      <!--此标签对应cookie的HttpOnly特性,默认为false,为了提高安全性,应将其设为true-->
      <http-only>true</http-only>
      <!--此标签对应cookie的Secure特性,默认为false,如果使用了HTTPS,应将其设为true-->
      <secure>false</secure>
      <!--此标签对应cookie的Max-Age特性,用于控制cookie的过期时间(单位:秒),默认没有过期时间(相当于设置为-1),
      即浏览器关闭就过期。最好保持默认值不变,正常情况下也不要去使用这个标签-->
      <max-age>1800</max-age>
    </cookie-config>
    <!--表示容器的追踪策略,可以设置一个或多个策略,从上到下安全等级递增,当使用了更高安全等级的策略就不可再使用低等级的策略-->
    <tracking-mode>URL</tracking-mode>
    <tracking-mode>COOKIE</tracking-mode>
    <tracking-mode>SSL</tracking-mode>
  </session-config>

        下面是一份常用的关于在部署描述 符中配置会话的简单配置:

<!--该配置设置会话过期时间为30分钟,追踪策略为COOKIE,使用HttpOnly特性来解决安全问题,其他的将接受默认值-->
  <session-config>
    <session-timeout>30</session-timeout>
    <cookie-config>
      <http-only>true</http-only>
    </cookie-config>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值