CAS 源码分析 (非proxy方式)
CAS 源码分析 (非proxy模式)?一、CAS 基本原理 ? (3,4,5,9.2,9.3是主要步骤)第一次访问:1. 浏览器 ? 发起访
CAS 源码分析 (非proxy模式)

?
一、CAS 基本原理 ? (3,4,5,9.2,9.3是主要步骤)
第一次访问:
1. 浏览器 ? 发起访问WebAPP 请求:? http://www.web.com/app
2. 客户端? AuthenticationFilter Filter 发现Session中无 Assertion,且URL中无 ticket 变量。生成 service url 变量,并重定向到:? https://www.cas-server.com/cas/login?service=http://www.web.com/app
3. CAS server? 生成 Login ticket, service 对象,并展示 login 页面,默认提供 username / password 给用户验证。
4. CAS server 端,用户输入 username / password 验证,若通过则生成TGT,存入服务器段(默认为 Map 类型的 cache),同时将TGT id 作为 content创建 cookie 并发送到浏览器。
5. CAS server 端通过TGT 生成service ticket.? 重定向到 http://www.web.com/app?ticket=ST-xxx
?
?
6. 客户端 ? 访问 http://www.web.com/app?ticket=ST-xxx
7. 客户端 ? AuthenticationFilter Filter 发现URL中有 ticket, 跳过 AuthenticationFilter过滤器,到达 Cas20ProxyReceivingTicketValidationFilter过滤器。
8. 客户端 生成验证 service url:? http://www.web.com/app
9. 客户端 ? Cas20ProxyReceivingTicketValidationFilter 过滤器,使用6处的ticket 与8处的 service 作为参数验证。
? 9.1? 客户端 生成验证 servlet: https://www.cas-server.com/cas/serviceValidate?ticket=ST-xxx&service=http://www.web.com/app
? 9.2? 客户端 通过HttpClient访问 9.1 的 url
??????????????? 注:AbstractUrlBasedTicketValidator.java line 207,如果是用CAS ptotocol验证,则第二个参数 ticket无用。
??????????????? 得到如下形式的 response:
public?final?void?doFilter(final?ServletRequest?servletRequest,?final?ServletResponse?servletResponse,?final?FilterChain?filterChain)?throws?IOException,?ServletException?{????????????if?(!preFilter(servletRequest,?servletResponse,?filterChain))?{??????????????return;??????????}????????????final?HttpServletRequest?request?=?(HttpServletRequest)?servletRequest;??????????final?HttpServletResponse?response?=?(HttpServletResponse)?servletResponse;??????????final?String?ticket?=?CommonUtils.safeGetParameter(request,?getArtifactParameterName());????????????//?如果?URL?中包含?ticket?参数,则执行?service?验证工作??????????if?(CommonUtils.isNotBlank(ticket))?{??????????????if?(log.isDebugEnabled())?{??????????????????log.debug("Attempting?to?validate?ticket:?"?+?ticket);??????????????}????????????????try?{???????????????????????????????????final?Assertion?assertion?=?this.ticketValidator.validate(ticket,?constructServiceUrl(request,?response));????????????????????if?(log.isDebugEnabled())?{??????????????????????log.debug("Successfully?authenticated?user:?"?+?assertion.getPrincipal().getName());??????????????????}????????????????????request.setAttribute(CONST_CAS_ASSERTION,?assertion);????????????????????if?(this.useSession)?{??????????????????????request.getSession().setAttribute(CONST_CAS_ASSERTION,?assertion);??????????????????}??????????????????onSuccessfulValidation(request,?response,?assertion);????????????????????if?(this.redirectAfterValidation)?{??????????????????????log.?debug("Redirecting?after?successful?ticket?validation.");??????????????????????response.sendRedirect(constructServiceUrl(request,?response));??????????????????????return;??????????????????}??????????????}?catch?(final?TicketValidationException?e)?{??????????????????response.setStatus(HttpServletResponse.SC_FORBIDDEN);??????????????????log.warn(e,?e);????????????????????onFailedValidation(request,?response);????????????????????if?(this.exceptionOnValidationFailure)?{??????????????????????throw?new?ServletException(e);??????????????????}????????????????????return;??????????????}??????????}????????????//?如果不包含?ticket,?直接跳过CAS?Filter验证,继续其他?filter?或?web?app?操作??????????filterChain.doFilter(request,?response);????????}