想学一些SSO单点登录的事情.在网上是找了很久,也找了些七七八八的信息.拿出来与大家分享一下.知识点比较杂.自己也是一知半解.还望大佬们多多指教..有一个小型框架,是跑通了项目,但是有几个不懂得地方,望大佬们多多指点.
- 开源的,多协议的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 Server,发现没有cookie,所以再重定向到CAS Server短的登陆页面,并且URL带有网站地址,便于认证成功后跳转.如:http ://cas-server:8100/login?service=http ://localhost:8081 Service后面这个地址就是登陆成功后要重定向的下游系统URL
- 在登陆页面输入用户名密码认证,认证成功后cas-server生成TGT,再用TGT生成一个ST.然后再第三次重定向并返回ST和cookie(TGC)到浏览器.
- 浏览器带着ST再访问想要访问的地址.如:http ://localhost:8081/?ticket=ST-25939-sqbDVZcuSvrvBC6MQlg5 ticket后面一串就是ST
- 浏览器的服务器收到ST后再去cas-server验证一下是否为自己签发的,验证通过后就会显示页面信息,也就是重定向到第一步service后面的那个URL. 此时首次登陆完毕
- 再登陆另一个接入CAS的网站,重定向到CAS Server,server判断是第一次来(但是此时有TGC,也就是cookie,所以不用去登陆页面了),但此时没有ST,去cas-server申请一个吧,于是重定向到cas-server.如:http: //cas-server:8100/login?service=http ://localhost:8082 && TGC(cookie) (传目标地址和cookie)
- cas-server生成了ST后重定向到浏览器 http ://localhost:8082/?ticket=ST-25939-sqfsafgefesaedswqqw5-xxxx
- 浏览器的服务器收到ST后再去cas-server验证一下是否为自己签发的.验证通过后就会显示页面信息(同上)
- 用户浏览器访问系统A需登陆受限资源,此时进行登陆检查,发现未登陆,然后进行获取票据操作,发现没有票据
- 系统A发现该请求需要登陆,将请求重定向到认证中心,获取全局票据操作.没有,进行,登陆.
- 认证中心呈现登陆页面,用户登陆,登陆成功后,认证中心重定向请求到系统A,并附上认证通过令牌,此时认证中心同时生成了全局票据
- 此时再次进行登陆检查,发现未登陆,然后再次获取票据操作,此时可以获取票据(令牌),系统A与认证中心通信,验证令牌有效,证明用户已经登陆.
- 系统A将受限资源返还给用户.
- 浏览器访问另一应用B需要登陆受限资源,此时进行登陆检查,发现未登陆,然后进行获取票据操作,发现没有票据
- 系统B发现该请求需要登陆,将请求重定向到认证中心,获取全局票据操作,获取全局票据,可以获得,认证中心发现已经登陆
- 认证中心发放临时票据(令牌),并携带该令牌重定向到系统B
- 此时再次进行登陆检查,发现未登陆,然后再次获取票据操作,此时可以获得票据(令牌),系统B与认证中心通信,验证令牌有效,证明用户已经登陆.
- 系统B将受限资源返还给客户端.
- 客户端向应用A发送登出Logout请求.
- 应用A取消本地会话,同时通知认证中心,用户已登出.
- 应用A返回客户端登出请求
- 认证中心通知所有用户登陆访问的应用.用户已登出.
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修改.
在本例中我们将使用Oracle数据库中自建一个用户表来管理我们的用户名和密码,因此:
- 将oracle的ojdbc6.jar放入tomcat的lib目录内D:\tomcat\lib
- 将cas-server-3.5.2-release\cas-server-3.5.2\modules下的这几个文件拷入tomcat\webapp\cas-server\web-inf\lib目录内
我的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.两者的差别还没怎么搞清楚,都好使用
<%@ 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标签中的链接地址不同.
<?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>