背景
对于一些比较复杂定制化登录页的情况下,之前提到过可以自定义修改使用CAS Server提供的登录页这种操作已经明显跟不上复杂定制场景了,所以CAS Server也提供了支持Restful接口,支持服务端后台登陆,对于复杂登陆场景时,可以使用接口后台进行认证CAS Server。
引入
在CAS Server中,引入restful接口依赖包
<!-- rest --> <dependency> <groupId>org.apereo.cas</groupId> <artifactId>cas-server-support-rest</artifactId> <version>6.5.9</version> </dependency>
重启CAS Server服务,在日志中能够看到如下日志:
说明restful接口已经成功引入了。
接口介绍
可以打开Spring MVC的扫描接口日志打印,可以看到有如下接口:
接口 | 参数说明 | 接口说明 |
---|---|---|
GET [/v1/tickets/{id:.+}] | 使用PathVariable接收参数,参数为ST票据。 | 用于校验ST票据状态 |
POST [/v1/tickets/{tgtId:.+}] | 使用PathVariable接收参数,参数为TGT;以及需要service作为表单参数使用application/x-www-form-urlencoded形式传递即可。 | 用于生成ST票据 |
POST [/v1/tickets] | 与CAS Server的UsernamePasswordCredential参数有关,默认为username和password参数,使用application/x-www-form-urlencoded形式传参。 | 获取TGT |
DELETE [/v1/tickets/{tgtId:.+}] | 使用PathVariable接收参数,参数为TGT。 | 删除TGT信息 |
GET [/v1/tickets] | 无。 | 不支持GET请求 |
POST [/v1/users] | 与CAS Server的UsernamePasswordCredential参数有关,默认为username和password参数,使用application/x-www-form-urlencoded形式传参。 | 获取当前CAS Server登陆的用户信息 |
后台认证示例
以Java语言作为示例,实现后台认证共分为三个步骤:
-
通过/v1/tickets接口获取到TGT信息
-
根据返回的TGT信息获取到ST票据
-
拼接ST票据重定向到指定接口即可完成认证
获取TGT信息
示例代码:
CloseableHttpClient httpClient = HttpClients.createDefault(); String tgtUrl = null; try { //1.获取tgt HttpPost httpPost = new HttpPost(casServerUrlPrefix + "/v1/tickets"); // 使用默认账号密码作为示例 List<BasicNameValuePair> data = new LinkedList<>(); data.add(new BasicNameValuePair("username", "casuser")); data.add(new BasicNameValuePair("password", "mellon")); HttpEntity httpEntity = new UrlEncodedFormEntity(data); httpPost.setEntity(httpEntity); CloseableHttpResponse execute = httpClient.execute(httpPost); HttpEntity entity = execute.getEntity(); String s = EntityUtils.toString(entity); tgtUrl = HtmlUtil.getAction(s); EntityUtils.consume(entity); } catch (Exception e) { // do nothing }
由于该接口返回的TGT信息如下:
<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\"> <html> <head> <title>201 CREATED</title> </head> <body> <h1>TGT Created</h1> <form action="http://localhost:8443/cas/v1/tickets/TGT-2-nx5h-5vzWsUzXBBNcY--WYT19d6FTuIQrv8G92Rx-3SCD2Gn3XWZbZMgFCUB4tzNYWg-DESKTOP-RV5J95A" method="POST">Service:<input type="text" name="service" value=""><br><input type="submit" value="Submit"></form> </body> </html>
所以需要从html中获取到action的TGT重定向信息,当前示例使用jsoup获取到TGT。
public class HtmlUtil { public static String getAction(String htmlContent) { Document parse = Jsoup.parse(htmlContent); Element body = parse.body(); Elements form = body.getElementsByTag("form"); Element element = form.get(0); return element.attr("action"); } }
获取ST票据
示例代码:
String st = null; //2.获取ST try { HttpPost httpPost = new HttpPost(tgtUrl); List<BasicNameValuePair> data = new LinkedList<>(); data.add(new BasicNameValuePair("service", serviceUrl)); HttpEntity httpEntity = new UrlEncodedFormEntity(data); httpPost.setEntity(httpEntity); CloseableHttpResponse execute = httpClient.execute(httpPost); st = EntityUtils.toString(execute.getEntity()); EntityUtils.consume(execute.getEntity()); } catch (Exception e) { e.printStackTrace(); }
需传递service重定向地址参数过去,该参数是用来绑定ST票据信息。
重定向地址
拿到ST票据信息之后,需拼接tickets={ST}参数并且页面重定向到上述serviceUrl接口,之前提到过解析ST时,或获取到重新向接口通过/p3/serviceValidate接口进行认证,如果重定向的接口并非service绑定的接口时,则CAS Server认证报错。
退出
使用CAS Server的页面登录,在退出的时候应该调用CAS Server的退出接口(/logout)。
在客户端服务中退出登陆,只要清除session即可;但是在清除客户端服务之后,再次访问客户端接口时,会跳转到CAS Server登录页面,但是由于CAS Server并没有退出,导致会直接重定向到访问客户端的接口,接口跳转如下:
图中,getData模拟客户端服务接口,由于CAS Server在登录的时候会写入Cookie,存在Cookie会导致重新登陆并且重定向回来。因此在客户端服务退出时,需调用CAS Server退出接口。
后台认证时,并未使用CAS Server登陆,如果重新访问CAS Server依旧是未登录状态,所以在退出的时候直接清除session即可。