cas login-webflow.xml分析。关于TGT何时生成和存储。

来源:互联网 发布:js 修改style left 编辑:程序博客网 时间:2024/06/11 09:02

1.首先设置一个变量credentials,保存账号密码等信息。

<var name="credentials" class="org.jasig.cas.authentication.principal.UsernamePasswordCredentials" />
</pre><p></p><p><span style="font-size:18px">2.执行initialFlowSetupAction的doExecute(final RequestContext context)方法。</span></p><p><span style="font-size:18px">参数RequestContext是流程的容器。</span></p><p></p><pre name="code" class="html"><on-start>        <evaluate expression="initialFlowSetupAction" />    </on-start>

doExecute方法先设置cookiePath为 /cas/ (默认为 / )。

再在 context.getFlowScope()里面保存:ticketGrantingTicketId,warnCookieValue,service

context.getFlowScope().put(            "ticketGrantingTicketId", this.ticketGrantingTicketCookieGenerator.retrieveCookieValue(request));        context.getFlowScope().put(            "warnCookieValue",            Boolean.valueOf(this.warnCookieGenerator.retrieveCookieValue(request)));        final Service service = WebUtils.getService(this.argumentExtractors,            context);        context.getFlowScope().put("service", service);



其中ticketGrantingTicketCookieGenerator,warnCookieGenerator,argumentExtractors由Spring注入,在ticketGrantingTicketCookieGenerator.xml,warnCookieGenerator.xml和argumentExtractorsConfiguration.xml文件中注册。

this.ticketGrantingTicketCookieGenerator.retrieveCookieValue(request)取出名字为CASTGC的cookie的值,由于还没有登陆,所以获得null。

Boolean.valueOf(this.warnCookieGenerator.retrieveCookieValue(request))判断名字为CASTGC的cookie的值是否为"true",由于还没有登陆,所以返回false。

 WebUtils.getService(this.argumentExtractors,context);取出service,不知道是什么,值为null。

进入decision-state节点。这些节点是依次执行的。

先检查flowScope中是否存在TGT

<!--检查flow中是否存在TGT如果存在,存在进入hasServiceCheck,为空进入gatewayRequestCheck-->  <decision-stateiddecision-stateid="ticketGrantingTicketExistsCheck">      <if test="flowScope.ticketGrantingTicketIdneq null"then="hasServiceCheck"else="gatewayRequestCheck"/>  </decision-state>  
因为是null,所有进入gatewayRequestCheck
<!--主要是 C/S使用gatway,不管--><decision-state id="gatewayRequestCheck"><if test="requestParameters.gateway != '' and requestParameters.gateway != null and flowScope.service != null" then="gatewayServicesManagementCheck" else="serviceAuthorizationCheck" /></decision-state>
很明显,service==null,所以,进入serviceAuthorizationCheck

<!-- Do a service authorization check early without the need to login first -->    <action-state id="serviceAuthorizationCheck">        <evaluate expression="serviceAuthorizationCheck"/>        <transition to="generateLoginTicket"/>    </action-state>
会执行evaluate expression="serviceAuthorizationCheck"的doExecute,这个在cas-servlet.xml中定义。

之后执行gentrateLoginTicket中generateLoginTicketAction的generate方法

<action-state id="generateLoginTicket">        <evaluate expression="generateLoginTicketAction.generate(flowRequestContext)" /><transition on="generated" to="viewLoginForm" /></action-state>
在cas-servlet.xml中bean为

<bean id="generateLoginTicketAction" class="org.jasig.cas.web.flow.GenerateLoginTicketAction"        p:ticketIdGenerator-ref="loginTicketUniqueIdGenerator"/>

该bean生成一个loginTicketId放入flowScope中。

其中loginTicketUniqueIdGenerator在uniqueIdGenerators.xml中定义。

但是这个loginTicketId并不是TGT。

接下来根据

<transition on="generated" to="viewLoginForm" />
返回一个登录页面。在登录页面上输入账号密码。

<view-state id="viewLoginForm" view="casLoginView" model="credentials">        <binder>            <binding property="username" />            <binding property="password" />        </binder>        <on-entry>            <set name="viewScope.commandName" value="'credentials'" />        </on-entry><transition on="submit" bind="true" validate="true" to="realSubmit">            <evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credentials)" />        </transition></view-state>
会执行authenticationViaFormAction.doBind()方法。这个方法不知道干嘛的。好像是把request和credentials关联到一起。

然后根据to="realSubmit"执行action-state

<action-state id="realSubmit">        <evaluate expression="authenticationViaFormAction.submit(flowRequestContext, flowScope.credentials, messageContext)" />        <!--      To enable LPPE on the 'warn' replace the below transition with:      <transition on="warn" to="passwordPolicyCheck" />      CAS will attempt to transition to the 'warn' when there's a 'renew' parameter      and there exists a ticketGrantingId and a service for the incoming request.    --><transition on="warn" to="warn" /><!--      To enable LPPE on the 'success' replace the below transition with:      <transition on="success" to="passwordPolicyCheck" />    --><transition on="success" to="sendTicketGrantingTicket" /><transition on="error" to="generateLoginTicket" /><transition on="accountDisabled" to="casAccountDisabledView" />    <transition on="mustChangePassword" to="casMustChangePassView" />    <transition on="accountLocked" to="casAccountLockedView" />    <transition on="badHours" to="casBadHoursView" />    <transition on="badWorkstation" to="casBadWorkstationView" />    <transition on="passwordExpired" to="casExpiredPassView" /></action-state>

执行authenticationViaFormAction.submit(flowRequestContext, flowScope.credentials, messageContext)方法。

这个方法会先判断flowScope和Request中保存的loginTicketId

final String authoritativeLoginTicket = WebUtils.getLoginTicketFromFlowScope(context);        final String providedLoginTicket = WebUtils.getLoginTicketFromRequest(context);        

这2个值必须相同,但是后面并没有再用到这2个值。

而是根据credentials ,生成一个TGT

String CASTGT=this.centralAuthenticationService.createTicketGrantingTicket(credentials);
把TGT放入requestScope中

WebUtils.putTicketGrantingTicketInRequestScope(context,tgt);

之后在login-webflow.xml中根据

<action-state id="sendTicketGrantingTicket">        <evaluate expression="sendTicketGrantingTicketAction" /><transition to="serviceCheck" /></action-state>

执行sendTicketGrantingTicketAction的doExecute方法。该方法应该是把TGT放到response的cookie中。

继续回到login-webflow.xml中

<decision-state id="serviceCheck"><if test="flowScope.service != null" then="generateServiceTicket" else="viewGenericLoginSuccess" /></decision-state>

如果service不为null则返回登录成功页面。否则返回renewRequestCheck。


renewRequestCheck又饶了一圈。





0 0
原创粉丝点击