1.若是两个网站域名的一级域名相同,可使用cookie和filter实现单点登陆,由于网站有可能(具体看cookie的设置)能够共享cookie。例如:www.bbs.aa.cn www.news.aa.cn。javascript
第一个网站在登陆后,把用户信息写到cookie中,当访问第二个网站时,第二个网站先通过本身的filter,检查session,若是没有,查询cookie,取出用户信息,放在session中登陆。php
\html
1其实单点登陆很简单前端
单点登陆的技术实现机制:当用户第一次访问应用系统1的时候,由于尚未登陆,会被引导到认证系统中进行登陆;根据用户提供的登陆信息,认证系统进行身份效验,若是经过效验,应该返回给用户一个认证的凭据--ticket;用户再访问别的应用的时候,就会将这个ticket带上,做为本身认证的凭据,应用系统接受到请求以后会把ticket送到认证系统进行效验,检查ticket的合法性。若是经过效验,用户就能够在不用再次登陆的状况下访问应用系统2和应用系统3了。java
能够看出,要实现SSO,须要如下主要的功能:web
a) 全部应用系统共享一个身份认证系统;apache
b) 全部应用系统可以识别和提取ticket信息;json
c) 应用系统可以识别已经登陆过的用户,能自动判断当前用户是否登陆过,从而完成单点登陆的功能windows
基于以上基本原则,本人用php语言设计了一套单点登陆系统的程序,目前已投入正式生成服务器运行。本系统程序,将ticket信息以全系统惟一的 session id做为媒介,从而获取当前在线用户的全站信息(登录状态信息及其余须要处理的用户全站信息)。后端
二. 过程说明:
登录流程:
1. 第一次登录某个站:
a) 用户输入用户名+密码,向用户验证中心发送登陆请求
b) 当前登陆站点,经过webservice请求,用户验证中心验证用户名,密码的合法性。若是验证经过,则生成ticket,用于标识当前会话的用户,并将当前登录子站的站点标识符记录到用户中心,最后
c) 将获取的用户数据和ticket返回给子站。若是验证不经过,则返回相应的错误状态码。
d) 根据上一步的webservice请求返回的结果,当前子站对用户进行登录处理:如状态码表示成功的话,则当前站点经过本站cookie保存ticket,并本站记录用户的登陆状态。状态码表示失败的话,则给用户相应的登陆失败提示。
2. 登录状态下,用户转到另外一子:
a) 经过本站cookie或session验证用户的登陆状态:如验证经过,进入正常本站处理程序;不然户中心验证用户的登陆状态(发送ticket到用户验证中心),如验证经过,则对返回的用户信息进行本地的登陆处理,不然代表用户未登陆。
登出流程
a) 当前登出站清除用户本站的登陆状态 和 本地保存的用户全站惟一的随机id
b) 经过webservice接口,清除全站记录的全站惟一的随机id。webservice接口会返回,登出其余已登陆子站的javascript代码,本站输出此代码。
c) js代码访问相应站W3C标准的登出脚本
WEB的登陆那些事
说道帐户登陆和注册,其实咱们天天都在亲身感觉着,像微博、知乎还有简书等等。咱们老是须要按期的去从新登陆一下,对于这种认证机制,咱们都能说出来两个名词,Cookie、Session。的确没错,Cookie和Session是实现这一切的核心。
为何会有Cookie和Session?区别是什么?
引入这两个概念的根本缘由是由于Http协议是无状态的,也就是说它不能创建起屡次请求之间的关系。因此须要引入一个能有浏览器或服务器保存的一个上下文状态,也就是Cookie和Session。说到底Session的实现是依赖于Cookie的,由于Cookie是真正的由浏览器保存的状态,Session是利用了JSessionID。在我看来其实二者有差别,可是根本的依赖是同样的。Cookie也是有生命周期的,像Session级别或者有必定“寿命”的Cookie。一切是由浏览器去维护的。
常见的跨域登陆问题
以前楼主主要是作帐户和Passport这方面的工做,其实在跨域这也是遇见了一些问题。
对于同一个根域下的登陆问题
若是咱们的站点有不止一个业务,那么他们可能部署在不一样的机器上,也每每须要不一样的域名进行区分。可是全部的业务又都是依赖于一套帐户体系,那么咱们这时候须要经过一次登陆解决全部站点的登陆问题,那么咱们这个时候可使用一个最笨的方法:那就是一次登陆成功,将Cookie写到根域下,那么这样全部的站点就能实现,同一个根域下的Cookie共享,天然实现了”单点登陆“。
对于多个根域下的登陆问题
若是是多个根域名,那么这种状况下上面的机制就不能实现“单点登陆”了。由于之因此上面能够实现“单点登陆”的效果。是由于浏览器和Http协议的支持。可是对于跨根域的站点之间进行Cookie的共享是比较复杂的。
方法1:登陆成功以后将Cookie回写到多个域名下。
这种办法可能十分简单,你能够经过后端的response写修改的是响应头信息 ,也能够用前端js去写,可是必须有对全部须要“单点登陆”的站点进行逐一的写入。用脚想这种办法也是行不通的,由于你须要维护一个站点的列表,维护工做十分复杂,同时对于增长站点也会特别痛苦。对于Cookie的销毁也是十分复杂的,由于仍是要对全部域名下的Cookie进行删除。也就是说将原来须要作的工做增长了n倍。对于小型站点这种办法是可取的。
方法2:jsonp
搞过前端的可能都知道用jsonp能够作跨域的请求,而咱们解决的就是多个域下的统一登陆的问题,好像很瓜熟蒂落的样子。可是,登陆是Server端作的吧?咱们在Client端作跨域的处理,这怎么看也不是很合理。同时这种办法须要很大的维护成本,每一次请求都要去固定的域下取相应的Cookie以后再作请求。想一想维护有头疼。
方法3 :引入一个中间态的Server
这种办法算是一个简化版的SSO,实现思想也十分的“狡猾”。可是对于小网站作跨域登陆的处理却十分的有用,具体思路以下:
首先,咱们有两个域名要实现单点登陆,同时咱们须要一个中间的Server。
咱们有一个系统域名为javahelp.com.cn,当咱们登陆的时候访问javahelp.com.cn/wp-login进行登陆,登陆成功以后将Cookie回写到javahelp这个域名下。
咱们还有一个系统域名为javaWeb.com,当咱们访问inside-javaWeb的时候,咱们没有Cookie,那么请求跳转到中间系统jump。此时须要将当前域名带到参数中便于jump校验。这个jump系统是在javahelp域下的即:jump.javahelp.net。这时候就能拿到以前写在javahelp域下的Cookie。
jump系统在收到了xulingbo域下的Cookie以后,取出xulingbo域下的Cookie,并redirect请求jump.inside-javaWeb.net,这个接口也是在jump系统中,请求后jump系统将Cookie回写到inside-javaWeb域名下,这样就实现了简易的单点登陆。以下图所示:
Paste_Image.png
可是这种方式不是很灵活,对于数据传输的安全性没有保障,而且在销毁Cookie的时候无能为力,只能所有遍历的销毁。
方法4:基于CAS的SSO系统
CAS可不是java中的Compare-And-Swap,它是一个开源的单点登陆系统(SSO)。实现的机制不算复杂可是思想十分灵巧。用CAS也能够快速实现单点登陆。盗图一张说明sso单个域的登陆和验证流程:
Paste_Image.png
CAS主要分为CAS Client 和CAS Server ,其中Client主要是内嵌在须要SSO登陆站点的拦截器或过滤器上。
首先浏览器向站点1发起请求。
站点1发现当前请求没有合法的Cookie,那么重定向到CAS Server上,也就是SSO Server。
CAS Server展现登陆界面,要求用户登陆。
用户登陆后,会写CAS Server的Cookie到浏览器,同时生产ticket,利用一个302跳转到CASClient。这样能保证用户无感知。
CAS Client利用生成的ticket发送到CAS Server进行验证,验证经过后,站点1生成本身的Cookie并回写到用户浏览器,而后进行登陆成功的跳转。
这样就能保证当前浏览器在站点1的域名下,有站点1的Cookie,同时当前浏览器也有CAS Server的Cookie。
接下来看下站点2的登陆:
Paste_Image.png
站点2,在进行登陆时和站点1初次登陆流程一致,可是在访问CAS Server的时候,因为当前浏览器已经有了CAS Server的Cookie,那么直接校验经过返回ticket。
ticket经过302跳转跳转到CAS Client上,以后的流程就和站点1是同样的了。若是此时认证失败,那么须要从新走一次登陆的过程。
其实感受很麻烦,可是流程却十分的简单,主要是使用CAS Server的Cookie作校验,同时各自系统维护本身的Cookie。
注意的问题:
CAS Server的Cookie劫持问题,若是CAS Server的Cookie被劫持掉,那么就至关于拿到了一切,因此必需要用HTTPS实现这个过程。
ticket的使用,ticket只能被使用一次,一次校验后当即失效。同时须要有时效性,通常5分钟。最后ticket生成规则要随机,不能被碰撞出来。
对于各自系统本身的Session,也能够依赖于SSO,这样就能保证全部的Session规则一致,便于集中控制。
其实SSO的实现很灵活,CAS只是说了一个原理,至于具体怎么实现,须要平衡安全性、易用性等诸多因素,因此也没有一个固定的实现方案。
SSO之CAS单点登陆实例演示
1、概述
此文的目的就是为了帮助初步接触SSO和CAS 的人员提供一个入门指南,一步一步演示如何实现基于CAS的单点登陆。
CAS的官网:http://www.jasig.org/cas
2、演示环境
本文演示过程在同一个机器上的(也能够在三台实体机器或者三个的虚拟机上),环境以下:
windows7 64位,主机名称:michael-pc
JDK 1.6.0_18
Tomcat 6.0.29
CAS-server-3.4.十一、CAS-client-3.2.1
根据演示需求,用修改hosts 文件的方法添加域名最简单方便(这个很是重要),在文件 C:\Windows\System32\drivers\etc\hosts 文件中添加三条
127.0.0.1 demo.micmiu.com
127.0.0.1 app1.micmiu.com
127.0.0.1 app2.micmiu.com
demo.micmiu.com=>> 对应部署cas server的tomcat,这个虚拟域名还用于证书生成
app1.micmiu.com=>> 对应部署app1 的tomcat
app2.micmiu.com=>> 对应部署app2 的tomcat
3、JDK安装配置
这个详细过程就不在描述,若是是免安装版的,确保环境变量配置正确。
本机环境变量:JAVA_HOME=D:\jdk,若是看到如下信息则表示安装成功:
4、安全证书配置
有关keytool工具的详细运用见:http://www.micmiu.com/lang/java/keytool-start-guide/
4.1. 生成证书:
1keytool -genkey -alias ssodemo -keyalg RSA -keysize 1024 -keypass michaelpwd -validity 365 -keystore g:\sso\ssodemo.keystore -storepass michaelpwd
截图中须要输入的姓名和上面hosts文件中配置的一致;
keypass 和 storepass 两个密码要一致,不然下面tomcat 配置https 访问失败;
4.2.导出证书:
1keytool -export -alias ssodemo -keystore g:\sso\ssodemo.keystore -file g:\sso\ssodem
4.3.客户端导入证书:
1keytool -import -keystore %JAVA_HOME%\jre\lib\security\cacerts -file g:\sso\ssodemo.crt -alias ssodem
ps:该命令中输入的密码和上面输入的不是同一个密码;若是是多台机器演示,须要在每一台客户端导入该证书。
5、部署CAS-Server相关的Tomcat
5.1. 配置HTTPS
解压apache-tomcat-6.0.29.tar.gz并重命名后的路径为 G:\sso\tomcat-cas,在文件 conf/server.xml文件找到:
修改为以下:
参数说明:
keystoreFile 就是4.1中建立证书的路径
keystorePass 就是4.1中建立证书的密码
5.2. 验证HTTPS配置
其余按照默认配置不做修改,双击%TOMCAT_HOME%\bin\startup.bat 启动tomcat-cas 验证https访问配置:
若是看到上述界面表示https 访问配置成功。
5.3 部署CAS-Server
CAS-Server 下载地址:http://www.jasig.org/cas/download
本文以cas-server-3.4.11-release.zip 为例,解压提取cas-server-3.4.11/modules/cas-server-webapp-3.4.11.war文件,把改文件copy到 G:\sso\tomcat-cas\webapps\ 目下,并重命名为:cas.war.
启动tomcat-cas,在浏览器地址栏输入:https://demo.micmiu.com:8443/cas/login ,回车
CAS-server的默认验证规则:只要用户名和密码相同就认证经过(仅仅用于测试,生成环境须要根据实际状况修改),输入admin/admin 点击登陆,就能够看到登陆成功的页面:
看到上述页面表示CAS-Server已经部署成功。
6、部署CAS-Client相关的Tomcat
6.1Cas-Client 下载
CAS-Client 下载地址:http://downloads.jasig.org/cas-clients/
以cas-client-3.2.1-release.zip 为例,解压提取cas-client-3.2.1/modules/cas-client-core-3.2.1.jar
借以tomcat默认自带的 webapps\examples 做为演示的简单web项目
6.2 安装配置 tomcat-app1
解压apache-tomcat-6.0.29.tar.gz并重命名后的路径为 G:\sso\tomcat-app1,修改tomcat的启动端口,在文件conf/server.xml文件找到以下内容:
修改为以下:
启动tomcat-app1,浏览器输入 http://app1.micmiu.com:18080/examples/servlets/ 回车:
看到上述界面表示tomcat-app1的基本安装配置已经成功。
接下来复制 client的lib包cas-client-core-3.2.1.jar到 tomcat-app1\webapps\examples\WEB-INF\lib\目录下, 在tomcat-app1\webapps\examples\WEB-INF\web.xml文件中增长以下内容:
有关cas-client的web.xml修改的详细说明见官网介绍:
https://wiki.jasig.org/display/CASC/Configuring+the+Jasig+CAS+Client+for+Java+in+the+web.xml
6.3 安装配置 tomcat-app2
解压apache-tomcat-6.0.29.tar.gz并重命名后的路径为 G:\sso\tomcat-app2,修改tomcat的启动端口,在文件 conf/server.xml文件找到以下内容:
修改为以下:
启动tomcat-app2,浏览器输入 http://app2.micmiu.com:28080/examples/servlets/ 回车,按照上述6.2中的方法验证是否成功。
同6.2中的复制 client的lib包cas-client-core-3.2.1.jar到 tomcat-app2\webapps\examples\WEB-INF\lib\目录下, 在tomcat-app2\webapps\examples\WEB-INF\web.xml文件中增长以下内容:
7、 测试验证SSO
启动以前配置好的三个tomcat分别为:tomcat-cas、tomcat-app一、tomcat-app2.
7.1 基本的测试
预期流程: 打开app1url —-> 跳转cas server 验证 —-> 显示app1的应用 —-> 打开app2url —-> 显示app2应用 —-> 注销cas server —-> 打开app1/app2 url —-> 从新跳转到cas server 验证.
打开浏览器地址栏中输入:http://app1.micmiu.com:18080/examples/servlets/servlet/HelloWorldExample,回车:
跳转到验证页面:
验证经过后显示以下:
此时访问app2就再也不须要验证:
地址栏中输入:https://demo.micmiu.com:8443/cas/logout,回车显示:
上述表示 认证注销成功,此时若是再访问 : http://app1.micmiu.com:18080/examples/servlets/servlet/HelloWorldExample 或 http://app2.micmiu.com:28080/examples/servlets/servlet/HelloWorldExample 须要从新进行认证。
7.2 获取登陆用户的信息
修改类:webapps\examples\WEB-INF\classes\HelloWorldExample.java 后从新编译并替换 webapps\examples\WEB-INF\classes\HelloWorldExample.class文件。
HelloWorldExample.java修改后的代码以下:
再进行上述测试显示结果以下:
http://app1.micmiu.com:18080/examples/servlets/servlet/HelloWorldExample :
http://app2.micmiu.com:28080/examples/servlets/servlet/HelloWorldExample
从上述页面能够看到经过认证的用户名。
到此已经所有完成了CAS单点登陆实例演示