CAS学习笔记(五)

来源:互联网 发布:scala 用 java的类 编辑:程序博客网 时间:2024/05/29 18:56

那么authenticationManager.authenticate()这个方法是如何进行认证的,关于认证的配置主要是在deployConfigContext.xml中定义的。

抽象类AbstrctauthenticationManager实现authenticationManager接口中的authenticate()方法,其中最主要的方法是final Pair

这里写图片描述

这是TGT和ST两种票据之间的关系

这里写图片描述

最后将产生的TGT放到一个hashmap中,在DefaultTicketRegistry.java类中实现。

这里写图片描述

这里写图片描述

authenticationViaFormAction的submit方法返回了success,即生成了TGT。根据webflow.xml:

这里写图片描述

跳转到id=sendTicketGrantingTicket中:

这里写图片描述

调用sendTicketGrantingTicketAction方法,它的主要作用是把上步骤产生的TGT放到respose中。应该是用户的浏览器中。返回success()
login-webflow判断是否有service,由于我们第一次输入的是客户端的url,所以携带service,接着产生ST。

这里写图片描述

对应cas-servlet.xml:

这里写图片描述

对应GenerateServiceTicketAction.java:

这里写图片描述

ST也是由核心类centralAuthenticationService.java生成的,注意,这个方法传入的参数含有前面生成的TGT和service。
grantServiceTicket方法的具体实现是位于TicketGrantingTicketImpl.java中。

这里写图片描述

方法描述:
1:生成SerivceTicketImpl
2:更新属性:
this.previousLastTimeUsed = this.lastTimeUsed;
this.lastTimeUsed = System.currentTimeMillis();
this.countOfUses++;
3:给service对象的principal属性赋值
4:将service对象放入map services

这里写图片描述

ST产生后,GenerateServiceTicketAction.generate方法返回success,login-webflow.xml接着判断在登陆界面登陆时是否已将勾选的复选框,以及是以get方法还是post方法传入。若无勾选,且以post传入。则成功跳转到客户端。

客户端:
当我们通过redirect返回之前的web客户端时,还会发生什么呢,这时有了TGT了,AuthenticationFilter中:

这里写图片描述

于是乎客户端进入了下一个filter Cas20ProxyReceivingTicketValidationFilter ,它的作用主要是对票据进行验证。
Cas20ProxyReceivingTicketValidationFilter过滤处理主要是其父类AbstractTicketValidationFilter实现。

这里写图片描述

实际上,服务器返回的Assertion是一段只含有用户名的html代码:

这里写图片描述

validate方法由AbstractBasedTicketValidator实现:

这里写图片描述

retrieveRespondeFromServer方法由Commonutils.java实现

这里写图片描述

此时:URL类似于https:${cas-server-host}:port/cas/serviceValidate?ticket=xxx&service=yyy

服务器端web.xml:

这里写图片描述

这个Servlet中包含有一个我们熟悉的Spring-MVC的前端分发器DispatcherServlet, 明显由它来奋发我们的请求,那么/validateService对应那个Controller呢?看cas-servlet.xml配置:

这里写图片描述

看一下serviceValidateController.java:
主要负责对service ticket的验证,失败返回casServiceValidationFailure.jsp,成功返回casServiceValidationSuccess.jsp
它实际上是调用了CentralAuthenticationService的validateServiceTicket方法。

成功之后,跳转到子系统,子系统AuthenticationFilter又进行了拦截:

这里写图片描述

由于已经登陆,assertion不为空,则退出

2、第二次登陆
客户端:用户输入客户端的URL,https://localhost:8443/App1
用户第二次登陆由于已经携带了TGT,主要不同之处是login-webflow.xml的判断:

这里写图片描述

下一步应该执行hasServiceCheck。进行一系列判断之后,直接产生ST:

这里写图片描述

接下去的步骤与第一次访问雷同,跳转到客户端之后,子系统AuthenticationFilter又进行了拦截:

这里写图片描述

assertion存在,实现了不需要再次进行登录。

3、CAS中数据流程

Credentials–>Principal–>Authentication

Credentials:取得客户输入的数据,或者可以理解为用户认证的凭据。
Principal:这个主要是保存认证后的用户信息。扩展信息放在一个Map中的。

Authentication:认证对象,就是一次认证后的结果对象,那么为啥不使

用Principal对象来作为认证结果呢?第一不是每次认证都是合法用户,对于不合法用户怎么办呢?其次,认证是一个动作,和这个动作本身相关的信息显然和用户信息是没有关系,例如认证时间。这个接口将Principal对象做了一次包装。也就是说可以通过Authentication接口可以访问到Principal对象。

附:CAS的一些核心接口的作用
 
 在CAS中很多地方使用了策略模式,那么根据什么方式来确定使用哪种策略呢?在很多策略类中有一个support(Credentials c)的方法,所以可以看出是根据Credentails的类型来决定使用哪种策略的。所以我们在AuthenticationHandler, CredentialsToPrincipalResolver,CredentialsBinder这些都可以看到support(Credentials c)方法。

下面是公用API列表,我们来一个个介绍这些接口的作用吧。

org.jasig.cas.CentralAuthenticationService:CAS核心,提供给HTTP,Web HTML, Web Services, RMI或者其他请求使用。能够创建,存储,验证和验证票据信息。
具有几个方法:

1)String createTicketGrantingTicket(Credentials credentials)
throws TicketException:根据凭证对象来创建一个TGT票据,那么凭证怎么来的呢?就是页面输入的信息,现在知道为啥TGT是和用户相关的凭证了吧。

2) String grantServiceTicket(String ticketGrantingTicketId, Service service)
throws TicketException:更具TGT和service来创建ST,从前面我们知道service就是接入的应用系统,那么ST就是用户(TGT)访问的service的票据。

3) String grantServiceTicket(final String ticketGrantingTicketId,final Service service, final Credentials credentials)throws TicketException:这个是干嘛的呢?
更具TGT和service来创建ST,从前面我们知道service就是接入的应用系统,那么ST就是用户(TGT)访问的service的票据。同时会给服务提供验证的credentials.

4)Assertion validateServiceTicket(final String serviceTicketId, final Service service) throws TicketException:很容易理解是不是,就是验证ST的,那么怎么返回一个Assertion对象,哦,对了,在前面介绍客户端配置票据验证的时候,是不是验证通过后会有一个xml格式的数据?明白了吧,就是个那个地方使用的。

5) void destroyTicketGrantingTicket(final String ticketGrantingTicketId):没啥好说了,票据不会一直创建下去,用户也不是一直在线,总需要退出,就算不退出也有一个时间限制吧,这个就是给登出或者超时后销毁和用户相关的TGT票据使用滴。

6) String delegateTicketGrantingTicket(final String serviceTicketId, final Credentials credentials) throws TicketException:文档说是给代理使用的

org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler

org.jasig.cas.authentication.handler.AuthenticationHandler:这个很好理解,就是实际验证的,只有两个方法:boolean authenticate(Credentials credentials)和 boolean supports(Credentials credentials)后面这个是不是很熟悉啊,对了,就是前面提到的策略模式中的supports方法,怎么认证方法只会返回true和false啊,那么用户信息怎么取得呢?别急嘛,右面有个CredentialsToPrincipalResolver接口专门来做这个事情滴。

org.jasig.cas.authentication.handler.PasswordEncoder:密码转换器

org.jasig.cas.authentication.principal.Credentials:取得客户输入的数据,或者可以理解为用户认证的凭据。就是需要认证用户身份需要的数据,每种认证方式需要信息是不一样的。这个只是一个类型接口,就是没有任何方法的接口啦。

org.jasig.cas.authentication.principal.CredentialsToPrincipalResolver:上面我们说到,Credentials对象是从界面或者别的什么地方取得用户信息,那么用户信息通过认证后怎么转换为Principal对象呢,这个就是这个解析器的作用了,由于认证本身是没有返回用户信息的,只是确定人中通过还是没有通过,所以取得用户信息需要另外一个非常重要的接口PersonAttributeDao,这个接口其实并不在CAS核心接口中的,是在一个叫person-directory-api-1.5.0-RC6.jar中的,这个包里面只有两个类,两个接口,那么实现有那些呢?是在person-directory-impl-1.5.0-RC6.jar,这个里面内容很丰富的。基本上你能想到的所有能取得用户信息的地方都有实现了。这个接口,也是一个策略,只有两个方法:supports , Principal resolvePrincipal(Credentials credentials),后面这个接口是不是很一目了然了?你可以理解我解析,或者更贴切点叫转换。
org.jasig.cas.authentication.principal.Principal:这个主要是保存认证后的用户信息。扩展信息放在一个Map中的。
org.jasig.cas.authentication.principal.Service:这个接口定义了和客户端相关的方法,例如登出服务器logOutOfService等动作。logOutOfService就是单点登出时候,怎么在服务器端登出所有访问过的客户端啦。

org.jasig.cas.authentication.principal.UsernamePasswordCredentials:用户用户名和密码访问的Credentials实现。
org.jasig.cas.authentication.Authentication:认证对象,就是一次认证后的结果对象,那么为啥不使用Principal对象来作为认证结果呢?第一不是每次认证都是合法用户,对于不合法用户怎么办呢?其次,认证是一个动作,和这个动作本身相关的信息显然和用户信息是没有关系,例如认证时间。这个接口将Principal对象做了一次包装。也就是说可以通过Authentication接口可以访问到Principal对象。
org.jasig.cas.validation.Assertion:这个接口主要是定义了,验证服务返回的对象,就是一个断言,你这个ST有没有权限访问,以及TGT访问的ST认证对象。
org.jasig.cas.web.bind.CredentialsBinder:这个是一个绑定器,将用户输入的信息或者从IE或者别的地方得到信息绑定到对应的凭证中去。使用spring web flew后,没有被使用了

0 0