最近在公司做了Web端单点登录(SSO)功能,基于Cookie实现,做完之后感觉有必要总结一下,本文着重讲解Cookie,下文会说明单点登录的实现方案。

Cookie简介

众所周知,Web协议(也就是HTTP)是一个无状态的协议(HTTP1.0)。一个Web应用由很多个Web页面组成,每个页面都有唯一的URL来定义。用户在浏览器的地址栏输入页面的URL,浏览器就会向Web

Server去发送请求。如下图,浏览器向Web服务器发送了两个请求,申请了两个页面。这两个页面的请求是分别使用了两个单独的HTTP连接。所谓无状态的协议也就是表现在这里,浏览器和Web服务器会在第一个请求完成以后关闭连接通道,在第二个请求的时候重新建立连接。Web服务器并不区分哪个请求来自哪个客户端,对所有的请求都一视同仁,都是单独的连接。这样的方式大大区别于传统的(Client/Server)C/S结构,在那样的应用中,客户端和服务器端会建立一个长时间的专用的连接通道。正是因为有了无状态的特性,每个连接资源能够很快被其他客户端所重用,一台Web服务器才能够同时服务于成千上万的客户端。
     
 但是我们通常的应用是有状态的。先不用提不同应用之间的SSO,在同一个应用中也需要保存用户的登录身份信息。例如用户在访问页面1的时候进行了登录,但是刚才也提到,客户端的每个请求都是单独的连接,当客户再次访问页面2的时候,如何才能告诉Web服务器,客户刚才已经登录过了呢?浏览器和服务器之间有约定:通过使用cookie技术来维护应用的状态。Cookie是可以被Web服务器设置的字符串,并且可以保存在浏览器中。如下图所示,当浏览器访问了页面1时,web服务器设置了一个cookie,并将这个cookie和页面1一起返回给浏览器,浏览器接到cookie之后,就会保存起来,在它访问页面2的时候会把这个cookie也带上,Web服务器接到请求时也能读出cookie的值,根据cookie值的内容就可以判断和恢复一些用户的信息状态。

Cookie组成

       cookie是由名称、内容、作用路径、作用域、协议、生存周期组成,另外还有个HttpOnly属性,HttpOnly属性很重要,如果您在cookie中设置了HttpOnly属性,那么通过js脚本(document.cookie)将无法读取到cookie信息,这样能一定程度上的防止XSS攻击,关于XSS可以看我之前的文章--XSS攻击及防御。Tomcat服务器设置的JSESSIONID就是HttpOnly的。
       JavaEE中对cookie做了封装,对应的是下面这个类:

java.lang.Object
|
+--javax.servlet.http.Cookie

该类可以设置cookie的名称、内容、作用路径、作用域、协议、生存周期,but不能设置HttpOnly属性,不知道这么做是出于什么考虑,如果非要设置HttpOnly的cookie,我们可以通过响应头来处理:

response.setHeader("Set-Cookie", "cookiename=value;Path=/;Domain=domainvalue;Max-Age=seconds;HttpOnly");

Cookie作用域
       测试Cookie的作用域需要弄几个域名,修改C:\Windows\System32\drivers\etc\hosts文件,将本机ip映射出四个域名,如下:

  1. 127.0.0.1 web1.ghsau.com
  2. 127.0.0.1 web2.ghsau.com
  3.  
  4. 127.0.0.1 web1.com
  5. 127.0.0.1 web2.com

前两个是2级域名(ghsau.com)相同,3级域名(web1、web2)不同,后两个是2级域名不同。然后我们再写两个jsp,一个用于设置Cookie,另一个用于显示Cookie。
       SetCookie.jsp:

  1. <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
  2. <%
  3. Cookie cookie = new Cookie("test_key", "test_value");
  4. cookie.setPath("/");
  5. // cookie.setDomain(".ghsau.com");
  6. response.addCookie(cookie);
  7. %>

ShowCookie.jsp:

  1. <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
  2. <%
  3. // 输出cookies,过滤掉JSESSIONID
  4. Cookie[] cookies = request.getCookies();
  5. if(cookies != null)
  6. for(Cookie cookie : cookies) {
  7. if(cookie.getName().equals("JSESSIONID")) continue;
  8. out.println(cookie.getName() + "-" + cookie.getValue());
  9. }
  10. %>

将这两个jsp放到应用后,部署到服务器中,启动服务器,我们就可以通过域名来访问了。
       测试一,首先访问http://web1.ghsau.com:8080/WebSSOAuth/SetCookie.jsp,设置cookie后,再访问http://web1.ghsau.com:8080/WebSSOAuth/ShowCookie.jsp,页面输出test_key=test_value,这时我们访问http://web2.ghsau.com:8080/WebSSOAuth/ShowCookie.jsp,发现页面什么都没有输出,这时我们得出结论,cookie默认情况下作用域为当前域名。
       测试二,将SetCookie.jsp第五行注释打开,按照上面的顺序依次访问,我们发现http://web2.ghsau.com:8080/WebSSOAuth/ShowCookie.jsp中输出了http://web1.ghsau.com:8080/WebSSOAuth/SetCookie.jsp中设置的cookie,这时我们得出结论,cookie作用域为父级域名时,所有子级域名都可以得到该cookie,这也是实现跨子域SSO的关键。这时有些朋友可能会想到那我把cookie作用域设置到顶级域名(.com、.net)上,是不是用该顶级域名的网站就都能获取该cookie了?这样设置的cookie,浏览器是不存储的,无效的cookie。

测试三,修改SetCookie.jsp第五行代码为cookie.setDomain(".web2.com"),首先访问http://web1.com:8080/WebSSOAuth/SetCookie.jsp,设置cookie后,这时我们访问http://web2.com:8080/WebSSOAuth/ShowCookie.jsp,发现页面什么都没有输出,这时我们得出结论,cookie不能跨二级域名设置。

Cookie安全性

cookie中的数据通常会包含用户的隐私数据,首先要保证数据的保密性,其次要保证数据不能被伪造或者篡改,基于这两点,我们通常需要对cookie内容进行加密,加密方式一般使用对称加密(单密钥,如DES)或非对称加密(一对密钥,如RSA),密钥需要保存在服务器端一个安全的地方,这样,别人不知道密钥时,无法对数据进行解密,也无法伪造或篡改数据。另外,像上文提到的,重要的cookie数据需要设置成HttpOnly的,避免跨站脚本获取你的cookie,保证了cookie在浏览器端的安全性。还有我们可以设置cookie只作用于安全的协议(https),JavaEE中可以通过Cookie类的setSecure(boolean

flag)来设置,设置后,该cookie只会在https下发送,而不会再http下发送,保证了cookie在服务器端的安全性,服务器https的设置可以参照该文章

Cookie深度解析的更多相关文章

  1. 【转】Cookie深度解析

    Cookie简介 众所周知,Web协议(也就是HTTP)是一个无状态的协议(HTTP1.0).一个Web应用由很多个Web页面组成,每个页面都有唯一的URL来定义.用户在浏览器的地址栏输入页面的URL ...

  2. 《SEO深度解析——全面挖掘搜索引擎优化的核心秘密》

    <SEO深度解析——全面挖掘搜索引擎优化的核心秘密> 基本信息 作者: 痞子瑞 出版社:电子工业出版社 ISBN:9787121224041 上架时间:2014-2-28 出版日期:201 ...

  3. Go netpoll I/O 多路复用构建原生网络模型之源码深度解析

    导言 Go 基于 I/O multiplexing 和 goroutine 构建了一个简洁而高性能的原生网络模型(基于 Go 的I/O 多路复用 netpoll),提供了 goroutine-per- ...

  4. Spring源码深度解析之Spring MVC

    Spring源码深度解析之Spring MVC Spring框架提供了构建Web应用程序的全功能MVC模块.通过策略接口,Spring框架是高度可配置的,而且支持多种视图技术,例如JavaServer ...

  5. [WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析

    [WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析 标签: webkit内核JavaScriptCore 2015-03-26 23:26 2285 ...

  6. 第37课 深度解析QMap与QHash

    1. QMap深度解析 (1)QMap是一个以升序键顺序存储键值对的数据结构 ①QMap原型为 class QMap<K, T>模板 ②QMap中的键值对根据Key进行了排序 ③QMap中 ...

  7. Deep Learning模型之:CNN卷积神经网络(一)深度解析CNN

    http://m.blog.csdn.net/blog/wu010555688/24487301 本文整理了网上几位大牛的博客,详细地讲解了CNN的基础结构与核心思想,欢迎交流. [1]Deep le ...

  8. (转载)(收藏)OceanBase深度解析

    一.OceanBase不需要高可靠服务器和高端存储 OceanBase是关系型数据库,包含内核+OceanBase云平台(OCP).与传统关系型数据库相比,最大的不同点, 是OceanBase是分布式 ...

  9. Kafka深度解析

    本文转发自Jason’s Blog,原文链接 http://www.jasongj.com/2015/01/02/Kafka深度解析 背景介绍 Kafka简介 Kafka是一种分布式的,基于发布/订阅 ...

随机推荐

  1. Github如何创建|删除仓库

    一.创建 1.1.点击官网(https://github.com/),注册并登陆后点击Start a project或者点击网页右上角的加号选择New repository 1.2.网址自动变更为ht ...

  2. 双列集合Map

    1.双列集合Map,就是存储key-value的键值对. 2.hashMap中键必须唯一,值可以不唯一. 3.主要方法:put添加数据    getKey---通过key获取数据    keySet- ...

  3. iOS 开发:绘制像素到屏幕

    转载:https://segmentfault.com/a/1190000000390012 译注:这篇文章虽然比较长,但是里面的内容还是很有价值的. 像素是如何绘制到屏幕上面的?把数据输出到屏幕的方 ...

  4. Dao层的sql语句

    2018-08-12     21:33:43 反思:在数据库执行的时候,sql语句是正确的,复制到方法中,执行出错   因为把限定条件改为?时,把左括号删掉了,sql语句报错 改正:一定要确保sql ...

  5. [Oracle][RAC]Oracle RAC环境里打OCW上的个别Patch,然后Rollback,发现OCW也被Rollback掉了

    对于Oracle RAC来说,存在着DB层面的Patch,也存在着GI层面的Patch. 本文介绍的是,GI层面,打Patch----> rollback 的动作之后,原来的OCW被Rollba ...

  6. main 团队项目厨娘:用例图、类图、时序图

    团队:main 项目:厨娘 个人用例图

  7. find -exec 批量使用方法

    查找当前目录批量文件内容后复制到指定目录当中 find . -type f -name "*.log" -exec cp {} /目标目录/ \;

  8. man 命令帮助文件输出乱码

    man 命令重定向的时候有写控制字符再直接显示的时候没有问题, 但是重定向到文件中的时候,被解释错误,显示为 ^H 或者乱码 解决方法: man ps | col -b >a.txt 可以消除所 ...

  9. 2/18 (pycharm 快捷键、循环、join语句)

    Alt + Enter 快速修正 Ctrl + / 行注释/取消行注释 Ctrl + Shift +  /  块注释 Ctrl + Alt + I    自动缩进 CTRL + D  复制选定的区域或 ...

  10. 北大poj- 1032

    Parliament Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18707   Accepted: 7941 Descr ...