SSO单点登录之初识CAS

想学一些SSO单点登录的事情.在网上是找了很久,也找了些七七八八的信息.拿出来与大家分享一下.知识点比较杂.自己也是一知半解.还望大佬们多多指教..有一个小型框架,是跑通了项目,但是有几个不懂得地方,望大佬们多多指点.

单点登录的英文名称为Single sign-on,简写为SSO,他是一个用户认证的过程,允许用户一次性进行认证之后,就访问系统中不同的应用;而不需要访问每一个应用时,都重新输入密码.IBM对SSO有一个形象的解释"单点登录,全网漫游";
实现SSO的方式有很多,现在主流的就是CAS这种基于session的单点登录形式.
CAS框架:CAS(Central Authentication Service)是实现SSO单点登录的框架.是Yale大学发起的一个企业级的.开源的项目,旨在为web应用系统提供一种可靠的单点登录解决方法(属于Web SSO)
CAS主要特性:
  • 开源的,多协议的SSO解决方案;Protocols:Constom Protocol.CAS.OAuth.openID.RESTfull API等.
  • 支持多种认证机制:Active Directory,JAAS,JDBC,LDAP等;
  • 安全策略:使用票据(Ticket)来实现支持的认证协议.
  • 支持授权;可以决定哪些服务可以请求和验证服务票据(Service Ticket)
  • 提供高可用性:通过把认证过的状态数据存储在TicketRegistry组件中,这些组件有很多支持分布式环境的实现,如:BerkleyDB,Default,EhcacheTicketRegistry,JDBCTicketRegistry,JBOSS TreeCache,JpaTicketRegistry 等
  • 支持多种客户端:Java,.net.PHP,Perl.Apache,uPortal等

CAS一般分为两部分,CAS Server和CAS Client
CAS Server用来负责用户的认证工作,就像是把第一次登陆用户的一个标识存在这里.以便此用户在其他系统登录时验证其需不需要再次登陆.
CAS Client就是我们自己的应用.需要接入CAS Server端.当用户访问我们的应用时,首先需要重定向到CAS Server端进行验证,要是原来登陆过,就免去登陆.重定向到下游系统,否则进行用户名密码登陆操作.

Ticket Granting ticket(TGT):可以认为是CAS Server根据用户名密码生成的一张票.存在server端.
Ticket granting cookie(TGC):其实就是一个cookie,存放用户身份信息,由server发给client端
Service ticket(ST):由TGT生成的一次性票据,用于验证,只能用一次.相当于server发给client一张票,然后client拿着这个票再来找server验证,看看是不是server签发的,就像是我给了你一张我的照片,然后你拿照片再来问我.这个照片是不是你,就是这么无聊.

基于CAS框架的流程:
  1. 用户访问网站,第一次来,重定向到CAS Server,发现没有cookie,所以再重定向到CAS Server短的登陆页面,并且URL带有网站地址,便于认证成功后跳转.如:http ://cas-server:8100/login?service=http ://localhost:8081 Service后面这个地址就是登陆成功后要重定向的下游系统URL
  2. 在登陆页面输入用户名密码认证,认证成功后cas-server生成TGT,再用TGT生成一个ST.然后再第三次重定向并返回ST和cookie(TGC)到浏览器.
  3. 浏览器带着ST再访问想要访问的地址.如:http ://localhost:8081/?ticket=ST-25939-sqbDVZcuSvrvBC6MQlg5 ticket后面一串就是ST
  4. 浏览器的服务器收到ST后再去cas-server验证一下是否为自己签发的,验证通过后就会显示页面信息,也就是重定向到第一步service后面的那个URL.  此时首次登陆完毕
  5. 再登陆另一个接入CAS的网站,重定向到CAS Server,server判断是第一次来(但是此时有TGC,也就是cookie,所以不用去登陆页面了),但此时没有ST,去cas-server申请一个吧,于是重定向到cas-server.如:http: //cas-server:8100/login?service=http ://localhost:8082 && TGC(cookie) (传目标地址和cookie)
  6. cas-server生成了ST后重定向到浏览器  http ://localhost:8082/?ticket=ST-25939-sqfsafgefesaedswqqw5-xxxx
  7. 浏览器的服务器收到ST后再去cas-server验证一下是否为自己签发的.验证通过后就会显示页面信息(同上)

流程概述:
访问服务:SSO客户端发送请求访问应用系统提供的服务资源
定向认证:SSO客户端会重定向用户请求到SSO服务器
用户认证:用户身份认证
发放票据:SSO服务器会产生一个随机的Service Ticket.
验证票据:SSO服务器验证票据Service Ticket的合法性,验证通过后,允许客户端访问服务.
传输用户信息:SSO服务器验证票据通过后,传输用户认证结果信息给客户端.

用户首次登陆的流程:
  1. 用户浏览器访问系统A需登陆受限资源,此时进行登陆检查,发现未登陆,然后进行获取票据操作,发现没有票据
  2. 系统A发现该请求需要登陆,将请求重定向到认证中心,获取全局票据操作.没有,进行,登陆.
  3. 认证中心呈现登陆页面,用户登陆,登陆成功后,认证中心重定向请求到系统A,并附上认证通过令牌,此时认证中心同时生成了全局票据
  4. 此时再次进行登陆检查,发现未登陆,然后再次获取票据操作,此时可以获取票据(令牌),系统A与认证中心通信,验证令牌有效,证明用户已经登陆.
  5. 系统A将受限资源返还给用户.
已登陆用户首次访问应用群中系统B时:
  1. 浏览器访问另一应用B需要登陆受限资源,此时进行登陆检查,发现未登陆,然后进行获取票据操作,发现没有票据
  2. 系统B发现该请求需要登陆,将请求重定向到认证中心,获取全局票据操作,获取全局票据,可以获得,认证中心发现已经登陆
  3. 认证中心发放临时票据(令牌),并携带该令牌重定向到系统B
  4. 此时再次进行登陆检查,发现未登陆,然后再次获取票据操作,此时可以获得票据(令牌),系统B与认证中心通信,验证令牌有效,证明用户已经登陆.
  5. 系统B将受限资源返还给客户端.

登陆状态判断:
用户到认证中心登陆后,用户和认证中心之间建立起了会话,我们把这个会话称为全局会话.当用户后续访问系统应用时,我们不可能每次应用请求都到认证中心去判定是否登陆,这样效率非常低下,这也是单Web应用不需要考虑的.
我们可以在系统应用和用户浏览器之间建立起局部会话,局部会话保持了客户端与该系统应用的登陆状态,局部会话依附于全局会话存在,全局会话消失,局部会话必须消失.
用户访问应用时,首先判断局部会话是否存在,如存在,即认为是登陆状态,无需再到认证中心去判断.如不存在,就重定向到认证中心判断全局会话是否存在.如存在,按1提到的方式通知该应用.该应用与客户端就建立起他们之间局部会话,下次请求该应用,就不去认证中心验证了.

登出:
用户在一个系统登出了.访问其他子系统,也应该是登出状态.要想做到这一点,应用除结束本地局部会话外,还应用通知认证中心该用户登出.
认证中心接到登出通知,即可结束全局会话,同时需要通知所有已建立全部会话的子系统,将他们的局部会话销毁.这样,用户访问其他应用时,都显示已登出状态.

整个登出流程如下:
  1. 客户端向应用A发送登出Logout请求.
  2. 应用A取消本地会话,同时通知认证中心,用户已登出.
  3. 应用A返回客户端登出请求
  4. 认证中心通知所有用户登陆访问的应用.用户已登出.

下面就是简单搭建框架的例子了/
准备两个zip文件,一个cas-server-3.5.2和cas-client-3.1.Tomcat7(端口号改为非8080,个人改为9090)

下载地址也贴出来吧.
CAS CLIENT的下载地址:   http://developer.jasig.org/cas-clients/

一切准备就绪,解压server,目录下找到cas-server-3.5.2\modules\cas-server-webapp-3.5.2.war复制到tomcat的webapp下面,并重命名为cas-server.war.启动tomcat/bin/startup.bat.黑窗口启动(如果闪屏,编辑startup.bat.内容首行添加:
SET JAVA_HOME=C:\Program Files\Java\jdk1.8.0_80(个人jdk路径)
SET TOMCAT_HOME=D:\test\apache-tomcat-7.0.78-windows-x64\apache-tomcat-7.0.78(个人tomcat路径)
同样shutdown.bat修改.
)
启动浏览器,localhost://9090/cas-server


显示如上,登陆成功.

配置server.添加jar包(这一步看到大佬的,我个人是略过了.现在没毛病,不知道之后会不会有bug出现)

在本例中我们将使用Oracle数据库中自建一个用户表来管理我们的用户名和密码,因此:

  1. 将oracle的ojdbc6.jar放入tomcat的lib目录内D:\tomcat\lib
  2. 将cas-server-3.5.2-release\cas-server-3.5.2\modules下的这几个文件拷入tomcat\webapp\cas-server\web-inf\lib目录内

以上个人都没有操作


修改配置文件

修改我们刚刚放到里面的tomcat下的tomcat/webapps/cas-server/web-inf/ deployerConfigContext.xml

我的zip没有找到war的打开方式,我就先压缩成zip,然后进去就可以找到需要的xml文件了.

注释掉 SimpleTestUsernamePasswordAuthenticationHandler的bean,相当于改成QueryDatabaseAuthenticationHandler

,

<!-- <bean 
   class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" /> -->
	<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">  
	<property name="dataSource" ref="dataSource" ></property>  
	<property name="sql" value="select password from sys_user where user_id=?" ></property>  
	</bean> 
此时property中有dataSource的引用.需要定义bean的id为datasource的bean

<bean id="dataSource"  
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
    <property name="driverClassName" value="oracle.jdbc.OracleDriver" />  
    <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl" />  
    <property name="username" value="ymk" />  
    <property name="password" value="password_1" />  
</bean>  

此时我们还要编辑CAS SSO的HTTPS认证模式:

cas-server.war\WEB-INF\spring-configuration\ticketGrantingTicketCookieGenerator.xml.



此时保存编辑后的文件,提示是否更新,当然要更新了.更新结束后.我是又重新解压.当然是看你的编辑方式..覆盖已经存在的war文件.


此时重新启动tomcat,输入地址localhost://9090/cas-server,跳转进之前的页面,用户admin,密码admin,提示如下:



如果,密码随便写,就是页面提示密码错误.



这样已经建好了.此时我们需要建立两个web工程.site1和site2.本文使用的是tomcat发布的两个web项目,有大佬用的jboss.两者的差别还没怎么搞清楚,都好使用



在webcontent下面新建index.jsp文件




index.jsp中的内容大概如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>cas site3</title>
</head>
<body>
	<h1>Hello,CAS TWO</h1>
	<a href="http://localhost:8080/site2/index.jsp">cas site2</a>  
	</br>  
	<a href="http://localhost:9090/cas-server/logout">退出</a>
</body>
</html>
两者中只是跳转的 a标签中的链接地址不同.

此时需要修改web.xml文件.此时的内容比较复杂..
<?xml version="1.0" encoding="UTF-8"?>  
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">  
      <display-name>site2</display-name>  
      <welcome-file-list>  
        <welcome-file>index.jsp</welcome-file>  
        <welcome-file>index.html</welcome-file>  
        <welcome-file>index.htm</welcome-file>      
        <welcome-file>default.html</welcome-file>  
        <welcome-file>default.htm</welcome-file>  
        <welcome-file>default.jsp</welcome-file>  
      </welcome-file-list>  
       <listener>  
            <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>  
      </listener>  
          
      <filter>  
            <filter-name>CAS Single Sign Out Filter</filter-name>  
            <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>  
      </filter>  
      <filter-mapping>  
            <filter-name>CAS Single Sign Out Filter</filter-name>  
            <url-pattern>*</url-pattern>  
      </filter-mapping>  
      
      <filter>  
            <filter-name>CAS Validation Filter</filter-name>  
            <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>  
            <init-param>  
                <param-name>casServerUrlPrefix</param-name>  
                <param-value>http://localhost:9090/cas-server</param-value>  
            </init-param>  
            <init-param>  
                <param-name>serverName</param-name>  
                <param-value>http://localhost:8080</param-value>  
            </init-param>  
            <init-param>  
                <param-name>useSession</param-name>  
                <param-value>true</param-value>  
            </init-param>  
            <init-param>  
                <param-name>redirectAfterValidation</param-name>  
                <param-value>true</param-value>  
            </init-param>  
      </filter>  
      <filter-mapping>  
            <filter-name>CAS Validation Filter</filter-name>  
            <url-pattern>*</url-pattern>  
      </filter-mapping>  
      
      <filter>  
            <filter-name>CAS Filter</filter-name>  
            <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>  
            <init-param>  
                <param-name>casServerLoginUrl</param-name>  
                <param-value>http://localhost:9090/cas-server/login</param-value>  
            </init-param>  
            <init-param>  
                <param-name>serverName</param-name>  
                <param-value>http://localhost:8080</param-value>  
            </init-param>  
      </filter>  
      <filter-mapping>  
            <filter-name>CAS Filter</filter-name>  
            <url-pattern>*</url-pattern>  
      </filter-mapping>  
      
      <filter>  
            <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>  
            <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>  
      </filter>  
      <filter-mapping>  
            <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>  
            <url-pattern>*</url-pattern>  
      </filter-mapping>  
    </web-app>  


此时保存所有...
eclipse中新建一个server,包含两个项目,一起发布.
启动tomcat,浏览器输入:http://8080/site2(根据自己的项目名称),跳转到cas-server登陆.密码正确,跳转到site页面.点击site3标签,跳转到登陆,密码正确到site3,此时
来回切换site2和site3,则无需输入密码,此时,点击退出,site2和site3均需要登陆才能访问.


几点不懂的地方,望大佬们指点:
1,没有引入ojdbc等jar,说明就没有使用本地oracle,事实证明确实没用,为什么使用admin/admin可以登录,其他是不可以登录的.这个admin是哪里来的?
2,首次登陆的时候,site2跳转的认证页面可以理解,为什么从site3跳转到site2时,还需要验证呢.??
3,logout时,需要清缓存或者重启浏览器,才可以实现完全清理,为什么???这样用户体验很差啊...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值