CAS项目登录流程介绍
cas是目前比较流行的SSL项目,他对于用户登录认证和用户授权访问资源都是实行了自己的一套协议。
cas的登录行为是用spring-webflow来控制。
首先从登陆的提交表单开始介绍,通过post方法访问“/cas/login”路径,改路径对应着webflow的入口,已配置在spring中。
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter"
p:flowExecutor-ref="flowExecutor" p:flowUrlHandler-ref="flowUrlHandler" />
<bean id="flowUrlHandler" class="org.jasig.cas.web.flow.CasDefaultFlowUrlHandler" />
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
<webflow:flow-execution-attributes>
<webflow:always-redirect-on-pause value="false" />
</webflow:flow-execution-attributes>
<webflow:flow-execution-repository max-executions="50" />
</webflow:flow-executor>
<webflow:flow-registry id="flowRegistry" flow-builder-services="builder">
<webflow:flow-location path="/WEB-INF/login-webflow.xml" id="login" />
</webflow:flow-registry>
注意flowRegistry的id为login和我们访问路径一致。login和每个webflow的对应关系由org.springframework.webflow.mvc.servlet.FlowHandlerAdapter控制,有其方法handle完成。
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
FlowHandler flowHandler = (FlowHandler) handler;
checkAndPrepare(request, response, false);
String flowExecutionKey = flowUrlHandler.getFlowExecutionKey(request);
if (flowExecutionKey != null) {
try {
ServletExternalContext context = createServletExternalContext(request, response);
FlowExecutionResult result = flowExecutor.resumeExecution(flowExecutionKey, context);
handleFlowExecutionResult(result, context, request, response, flowHandler);
} catch (FlowException e) {
handleFlowException(e, request, response, flowHandler);
}
} else {
try {
String flowId = getFlowId(flowHandler, request);
MutableAttributeMap input = getInputMap(flowHandler, request);
ServletExternalContext context = createServletExternalContext(request, response);
FlowExecutionResult result = flowExecutor.launchExecution(flowId, input, context);
handleFlowExecutionResult(result, context, request, response, flowHandler);
} catch (FlowException e) {
handleFlowException(e, request, response, flowHandler);
}
}
return null;
}
注意 getFlowId方法这里是决定启用哪个flow的地方。此处代码被flowExecutionKey 分成两段,是flowExecutionKey 确定每次请求是新的流程还是已经存在的流程中。
下面进入结合cas配置的web-flow来介绍下登录流程是如何进行的
首先是initialFlowSetupAction,每次都回运行这个bean,它被设置为on-start
<on-start>
<evaluate expression="initialFlowSetupAction" />
</on-start>
protected Event doExecute(final RequestContext context) throws Exception {
final HttpServletRequest request = WebUtils.getHttpServletRequest(context);
if (!this.pathPopulated) {
final String contextPath