如何通过REST调用实现Apereo CAS跨应用登录并获取验证令牌?
Java应用调用Apereo CAS完成JSON登录并获取验证令牌
当然可以通过CAS的REST API实现这个需求,以下是具体的实现步骤和代码示例:
前提:开启CAS REST认证模块
CAS默认未启用REST支持,需要修改CAS服务器配置(比如cas.properties或Spring Boot配置类):
cas.authn.rest.enabled=true
配置后重启CAS服务器。
核心流程
CAS的REST登录分为两步:先获取TGT(Ticket Granting Ticket,票据授予票据),再用TGT获取针对特定业务服务的ST(Service Ticket,服务票据)。
1. 发送JSON请求获取TGT
调用CAS的/cas/v1/tickets端点,POST提交JSON格式的用户名和密码,请求头需设置Content-Type: application/json。
Java代码示例(使用OkHttp库):
import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; import java.io.IOException; public class CasLoginClient { public static void main(String[] args) throws IOException { // 本地CAS用自签证书时,临时跳过验证(生产环境务必替换为信任证书配置) OkHttpClient client = new OkHttpClient.Builder() .hostnameVerifier((hostname, session) -> true) .build(); MediaType JSON = MediaType.get("application/json; charset=utf-8"); String loginPayload = "{\"username\":\"casuser\",\"password\":\"Mellon\"}"; RequestBody body = RequestBody.create(loginPayload, JSON); Request request = new Request.Builder() .url("https://localhost:8443/cas/v1/tickets") .post(body) .addHeader("Content-Type", "application/json") .build(); try (Response response = client.newCall(request).execute()) { if (response.isSuccessful()) { // TGT的ID在响应头的Location字段中提取 String tgtLocation = response.header("Location"); String tgtId = tgtLocation.substring(tgtLocation.lastIndexOf("/") + 1); System.out.println("TGT获取成功:" + tgtId); // 用TGT获取业务服务对应的服务票据 getServiceTicket(client, tgtId, "https://your-app-service-url.com"); } else { System.err.println("登录失败:" + response.body().string()); } } } // 获取服务票据(ST) private static void getServiceTicket(OkHttpClient client, String tgtId, String serviceUrl) throws IOException { MediaType FORM = MediaType.get("application/x-www-form-urlencoded"); RequestBody body = RequestBody.create("service=" + serviceUrl, FORM); Request request = new Request.Builder() .url("https://localhost:8443/cas/v1/tickets/" + tgtId) .post(body) .build(); try (Response response = client.newCall(request).execute()) { if (response.isSuccessful()) { String serviceTicket = response.body().string(); System.out.println("服务票据获取成功:" + serviceTicket); // 后续可将ST传给你的业务服务,由服务端调用CAS验证有效性 } else { System.err.println("获取服务票据失败:" + response.body().string()); } } } }
2. 验证服务票据(可选)
拿到ST后,你的业务服务可以调用CAS的/cas/p3/serviceValidate端点验证ST的合法性,示例请求:
GET https://localhost:8443/cas/p3/serviceValidate?service=https://your-app-service-url.com&ticket={ST}
响应为XML格式,包含用户身份信息等验证结果。
注意事项
- 生产环境禁止跳过证书验证,需将CAS服务器的证书导入Java应用的信任库。
- TGT是长期票据,可缓存用于多次获取ST,但需注意CAS服务器的会话超时配置。
- ST是一次性票据,验证后即失效。
内容的提问来源于stack exchange,提问作者justAUser
相关产品推荐
相关产品推荐

