背景
最近Java项目需要一个CAS client做用户静默登录,需求:CAS客户端需要登录、登出用户以及用户CAS授权校验。CAS Java官方客户端 Apereo Java CAS Client 看了文档不知所以然,找不到对于授权等验证API。没有phpCAS一样方便(之前有写过php集成CAS教程:Laravel使用phpCAS注意点),还好CAS还提供了REST协议,本文就基于CAS REST协议获取TGT、ST已经验证ST获取username。
第一步:获取TGT(Ticket Granting Ticket)
POST /cas/v1/tickets HTTP/1.0
'Content-type': 'application/x-www-form-urlencoded'
username=battags&password=password&additionalParam1=paramvalue
注意点:
用户名密码正确
Content-type必须是application/x-www-form-urlencoded
成功响应:
201 Created
Location: http://www.mango.im/cas/v1/tickets/{TGT id}
返回结果是一段HTML
<html>
<head>
<title>201 The request has been fulfilled and resulted in a new resource being created</title></head>
<body>
<h1>TGT Created</h1>
<form action="http://www.mango.im/cas/v1/tickets/TGT-10284-bq6qKkQCY3Hne4kFxWLux0Lkebnyhj7Kkyu6zsl6ze0CBadS7h-www.mango.im" method="POST">Service:
<input type="text" name="service" value="">
<br>
<input type="submit" value="Submit"></form></body>
</html>
我们需要把TGT提取出来,Java示例代码:
Pattern pattern = Pattern.compile("(?<=tickets/)([\\w-.]+)");
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
logger.info("TGT:"+matcher.group());
tgt = matcher.group();
}
失败响应:
如果发送了错误的凭据,则CAS将响应400 Bad Request错误(也将针对缺少的参数等进行响应)。 如果发送的媒体类型无法识别,它将发送415不支持的媒体类型。
第二步:获取ST(Service Ticket)
通过TGT获取ST
POST /cas/v1/tickets/{TGT id} HTTP/1.0
service={form encoded parameter for the service url}
注意点:service参数必须是urlencode的url。
成功响应:
200 OK
ST-1-FFDFHDSJKHSDFJKSDHFJKRUEYREWUIFSD2132
第三步:校验ST(Service Ticket)
GET /cas/p3/serviceValidate?service={service url}&ticket={service ticket}
注意点:service url需要和第二步获取的ST service url一致,也必须是urlencode过的。
成功响应:
200 ok
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationSuccess>
<cas:user>mango</cas:user>
</cas:authenticationSuccess>
</cas:serviceResponse>
至此整个授权过程就结束了。
总结
CAS REST接口调用比较简单,但响应内容格式不统一,有HTML,字符串,XML需要对每种返回结果做处理。
另外请求的service需要保证一致,否则校验不通过Ticket not recognized。调试过程遇到错误看下CAS server日志,错误信息很详细,对排查问题很有帮助。
CAS流程图
参考文档:https://apereo.github.io/cas/6.0.x/protocol/REST-Protocol.html