本文旨在让初次接触CAS的同学不那么迷惑,我会一步步将调试的过程详细的分享在这里。包括参数的请求,类设计等。如果问CAS 本身是什么,在这不多做解释。不懂请Google。
CAS 总共分为两套系统。一套“进行认证授权的系统”,一套“需要认证与授权的系统”。那么今天我们探讨下CAS “需要认证与授权系统”的工作流程。
1. 首先从web.xml开始,找到edu.yale.its.tp.cas.client.filter.CASFilter
2.Session中是否存在票据:(如果存在票据,则直接doFilter)
// if our attribute's already present and valid, pass through the filter chain
CASReceipt receipt = (CASReceipt)
session.getAttribute(CAS_FILTER_RECEIPT);
if (receipt != null && isReceiptAcceptable(receipt)) {
fc.doFilter(request, response);
return;
}
检测parameter中是否存在票据参数,因为可能是第一次通过CAS Server 返回ticket
// otherwise, we need to authenticate via CAS
String ticket = request.getParameter("ticket");
如果parameter中也没有发现ticket则施行跳转操作,中止链,跳转到CAS Server,当前程序返回
redirectToCAS((HttpServletRequest) request,
(HttpServletResponse) response);
// abort chain
return;
那么跳转应该有哪些参数呢?
https://localhost:8444/cas/login?service=http%3A%2F%2Flocalhost%3A8080%2FSSOClient%2Findex.jsp
经过在client端Filter上的数据配置,获得需要跳转到server的URL地址。这是最终要跳转的页面:需要跳转到cas的login上,并且需要附带上service的地址,也就是当前用户访问的cas client 项目地址。因为当在cas service上验证通过后,还需要返回到该地址,再进行一次验证操作。
获得该地址后使用方法跳转
((HttpServletResponse) response).sendRedirect(casLoginString);
程序到此告一段落,需要到server中进一步调试。
当在server 提供了正确的凭证以后客户端会执行的操作:
// otherwise, we need to authenticate via CAS
String ticket = request.getParameter("ticket");
Ticket不会为空:“ST-1-rTFOP12QkKDtSAwuZ7Oq”
使用此代理检测票据。ProxyTicketValidator
此代理需要的数据有:
pv = new ProxyTicketValidator();
pv.setCasValidateUrl(casValidate);
pv.setServiceTicket(request.getParameter("ticket"));
pv.setService(getService(request));
pv.setRenew(Boolean.valueOf(casRenew).booleanValue());
设置的具体参数值为:
CasValidateUrl = https://localhost:8444/cas/serviceValidate
Ticket = ST-1-rTFOP12QkKDtSAwuZ7Oq
Service = http%3A%2F%2Flocalhost%3A8080%2FSSOClient%2Findex.jsp
casRenew = false
验证ProxyTicketValidator
组装形成的URL为:
https://localhost:8444/cas/serviceValidate?service=http%3A%2F%2Flocalhost%3A8080%2FSSOClient%2Findex.jsp&ticket=ST-1-rTFOP12QkKDtSAwuZ7Oq
使用URLConnection的方式请求了serviceValidate
URLConnection uc = u.openConnection();
uc.setRequestProperty("Connection", "close");
r = new BufferedReader(new InputStreamReader(uc.getInputStream()));
String line;
StringBuffer buf = new StringBuffer();
while ((line = r.readLine()) != null)
buf.append(line + "\n");
return buf.toString();
返回的结果是:
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationSuccess>
<cas:user>aaa</cas:user>
</cas:authenticationSuccess>
</cas:serviceResponse>
12.
通过XMLReader r =
SAXParserFactory.newInstance().newSAXParser().getXMLReader();解析返回的xml文件
13. 通过XMLReader的解析,将xml的值设置在ptv中。再新new CASReceipt对象,进行设置值。 CASReceipt receipt = new CASReceipt();
receipt.casValidateUrl = ptv.getCasValidateUrl();
receipt.pgtIou = ptv.getPgtIou();
receipt.userName = ptv.getUser();
receipt.proxyCallbackUrl = ptv.getProxyCallbackUrl();
receipt.proxyList = ptv.getProxyList();
receipt.primaryAuthentication = ptv.isRenew();
在进行receipt的validate检查userName,casValidateUrl,proxyList,等值是否为空。
各项验证成功后
if (session != null) { // probably unnecessary
session.setAttribute(CAS_FILTER_USER, receipt.getUserName());
session.setAttribute(CASFilter.CAS_FILTER_RECEIPT, receipt);
// don't store extra unnecessary session state
session.removeAttribute(
CAS_FILTER_GATEWAYED);
}
向session中设置登录成功的用户,收据,
// continue processing the request
fc.doFilter(request, response);
log.trace("returning from doFilter()");
下一篇将介绍CAS “进行认证授权系统”的工作流程与类设计