1 单点登录的概念
1.1什么是单点登录
单点登录是指在多系统共存的情况下,用户在一个系统登录之后,可以通过某种授权机制登录到其他的系统内。大型的网站内,会存在着多个子系统,如果每个系统都需要单独的进行登录认证,会非常的麻烦。单点登录系统的实现,必须要保证:
1.1.1传统系统的登录认证如下:
简单系统的登录认证主要依靠的是Cookie中的jsessionid参数,服务器端会根据jsessionid校验Session是否合法。所以实现单点登录,就可能存在跨多个域名,如果以普通的登录来实现,肯定是不能实现的,Cookie的跨域问题,访问另外一个站点,jsessionid属于Cookie的值,不能进行跨域的Cookie传递,就导致了认证失败。
1.1.2单点登录的简单实现:
单点登录作为认证中心的存在,要求所有的系统在认证中心进行认证。所以访问某个应用时,没有登录,服务器重定向到浏览器跳转到认证中心登录,则认证的表示就可以通过Cookie传递到认证中心。
2 CAS单点登录详解:
2.1CAS术语解释:
1) TGT(存放在CAS server中)
存放在CAS server端。其中key为TGC,当有请求到达Cas Server端时,以TGC为key查询缓存中是否有对应的TGT,如果有,则证明登录过,返回一个唯一标示CAS应用的Service ticket。
2) TGC(存放在客户端浏览器中):
Cas server认证过后,返回给客户端浏览器的Cookit值,path为/。
3) ST(service ticket):
每一个Cas应用认证成功之后,都会返回一个Service ticket给客户端。
4) CAS Server认证中心服务器,负责系统的统一认证
5)Cas-client:系统加入单点登录,需要加载cas-client-core.jar,并且在web.xml中配置对应的Filter,登录和回调,依靠这些Filter.
2.2CAS单点登录时序图
认证总体说明:
1)客户端浏览器第一次访问APP1(http://www.app1.com),APP1中存储的没有Session信息,客户端浏览器也没有携带Ticket参数,所以会重定向到Cas Server进行认证
2)Cas Server首先会读取cookie中的TGC,由于是第一个系统认证,TGC不存在,会要求用户进行登录。(http://www.sso.com?service=www.app1.com)
3)登录成功之后,根据service参数,进行重定向,Cas Server会生成TGT保存在认证中心服务器的缓存中,同时生成一个一级域名下的Cookie(TGC),返回给客户端浏览器(http://www.app1.com?ticket=.....)
4)App1根据Cas-client中的Filter进行请求的拦截,并且校验Ticket,根据Ticket从SSO获取用户名等信息。验证成功,创建本地的Session。完成SSO的登录
5)用户访问应用2(App2)时,没有Session,也没有ticket,重定向到认证中心。由于已经认证过,cookie中携带TGC去认证,认证中心根据TGC读取TGT中的内容,读取到之后,为App2创建一个ticket参数,重复步骤4、5按成系统的认证。
2.3使用浏览器调试CAS认证的过程.
a )第一次访问应用,会被重定向到认证中心(访问http://www.app1.com:8080/examples/servets),判断是否登录,如果没有TGC这个Cookie,认证中心会重定向到登录页面。
b)提交用户名和密码进行认证
认证通过,
服务器端生成TGT缓存到认证中心服务器。
生成APP1对用的ticket,附加在回调地址中的参数中。
生成和认证中心对应域的Cookie(TGC),写入到浏览器中。
c )第二个应用访问时,APP2没有Session,没有Ticket,重定向到认证中心,携带TGC参数,到认证中心进行认证,根据TGC去TGT中验证,验证成功,返回一个唯一的Ticket。
2.4CAS客户端的配置
配置web.xml
2.4.1认证过滤器配置
<filter> <filter-name>CASFilter</filter-name> <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class> <init-param> <param-name>casServerLoginUrl</param-name> <!--SSO server的地址--> <param-value>http://192.168.233.133:8080</param-value> </init-param> <init-param> <param-name>serverName</param-name> <!--应用的回调地址(service参数....)--> <param-value>http://localhost:8080</param-value> </init-param> </filter> <filter-mapping> <filter-name>CASFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> |
2.4.2Ticket校验的配置
<filter> <filter-name>CASValidation Filter</filter-name> <filter-class> org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class> <init-param> <param-name>casServerUrlPrefix</param-name> <param-value>http://192.168.233.133:8080</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>CASValidation Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
2.4.3配置过滤器获取用户名
<filter> <filter-name>CASHttpServletRequest Wrapper Filter</filter-name> <filter-class> org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class> </filter> <filter-mapping> <filter-name>CASHttpServletRequest Wrapper Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。 比如AssertionHolder.getAssertion().getPrincipal().getName()。 --> <filter> <filter-name>CASAssertion Thread Local Filter</filter-name> <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class> </filter> <filter-mapping> <filter-name>CASAssertion Thread Local Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>