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。