H__D  

1. 登录流程

登录流程分为以下步骤:

  1. 获取 TGT(Ticket Granting Ticket)

    • 使用用户名和密码向 CAS 的 /cas/v1/tickets 接口发送 POST 请求,获取 TGT。

  2. 获取 ST(Service Ticket)

    • 使用 TGT 向 CAS 的 /cas/v1/tickets/{TGT} 接口发送 POST 请求,获取 ST。

  3. 验证 ST

    • 使用 ST 向 CAS 的 /cas/p3/serviceValidate 接口发送 GET 请求,验证 ST 并获取用户属性。


2. 登出流程

登出流程分为以下步骤:

  1. 注销 TGT

    • 使用 TGT 向 CAS 的 /cas/v1/tickets/{TGT} 接口发送 DELETE 请求,注销 TGT。

  2. 注销 ST

    • 使用 ST 向 CAS 的 /cas/v1/tickets/{ST} 接口发送 DELETE 请求,注销 ST。


3. 调用 CAS REST API 的示例代码

   示例中,关于客户端验证 CAS 服务器的 SSL 证书问题,使用的时临时解决方案

  • 临时解决方案:使用 HTTP 或忽略 SSL 证书验证(仅用于测试)。

  • 推荐解决方案:将 CAS 服务器的 SSL 证书导入客户端的信任库,或使用有效的 SSL 证书。

  • 生产环境:建议使用有效的 SSL 证书,并确保客户端信任该证书。

复制代码
package com.test.springboot;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;

public class CasRestClient {

    private static final String CAS_BASE_URL = "https://localhost:8443/cas";
    private static final String SERVICE_URL = "https://www.apereo.org";

    public static void main(String[] args) throws IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        // 1. 获取 TGT
        String tgt = getTgt("admin", "password");
        System.out.println("TGT: " + tgt);

        // 2. 获取 ST
        String st = getSt(tgt, SERVICE_URL);
        System.out.println("ST: " + st);

        // 3. 验证 ST
        String userAttributes = validateSt(st, SERVICE_URL);
        System.out.println("User Attributes: " + userAttributes);

        // 4. 注销 ST
        logoutSt(st);
        System.out.println("ST logged out");

        // 5. 注销 TGT
        logoutTgt(tgt);
        System.out.println("TGT logged out");
    }

    private static String getTgt(String username, String password) throws IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        String url = CAS_BASE_URL + "/v1/tickets";
        HttpPost request = new HttpPost(url);
        request.setHeader("Content-Type", "application/x-www-form-urlencoded");
        request.setEntity(new StringEntity("username=" + username + "&password=" + password));

        try (CloseableHttpClient client = createInsecureHttpClient()) {
            HttpResponse response = client.execute(request);
            if (response.getStatusLine().getStatusCode() == 201) {
                return response.getFirstHeader("Location").getValue();
            } else {
                throw new RuntimeException("Failed to get TGT: " + response.getStatusLine());
            }
        }
    }

    private static String getSt(String tgt, String serviceUrl) throws IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        String url = tgt;
        HttpPost request = new HttpPost(url);
        request.setHeader("Content-Type", "application/x-www-form-urlencoded");
        request.setEntity(new StringEntity("service=" + serviceUrl));

        try (CloseableHttpClient client = createInsecureHttpClient()) {
            HttpResponse response = client.execute(request);
            if (response.getStatusLine().getStatusCode() == 200) {
                return EntityUtils.toString(response.getEntity());
            } else {
                throw new RuntimeException("Failed to get ST: " + response.getStatusLine());
            }
        }
    }

    private static String validateSt(String st, String serviceUrl) throws IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        String url = CAS_BASE_URL + "/p3/serviceValidate?ticket=" + st + "&service=" + serviceUrl;
        HttpGet request = new HttpGet(url);

        try (CloseableHttpClient client = createInsecureHttpClient()) {
            HttpResponse response = client.execute(request);
            if (response.getStatusLine().getStatusCode() == 200) {
                return EntityUtils.toString(response.getEntity());
            } else {
                throw new RuntimeException("Failed to validate ST: " + response.getStatusLine());
            }
        }
    }

    private static void logoutTgt(String tgt) throws IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        String url = tgt;
        HttpDelete request = new HttpDelete(url);

        try (CloseableHttpClient client = createInsecureHttpClient()) {
            HttpResponse response = client.execute(request);
            if (response.getStatusLine().getStatusCode() != 200) {
                throw new RuntimeException("Failed to logout TGT: " + response.getStatusLine());
            }
        }
    }

    private static void logoutSt(String st) throws IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        String url = CAS_BASE_URL + "/v1/tickets/" + st;
        HttpDelete request = new HttpDelete(url);

        try (CloseableHttpClient client = createInsecureHttpClient()) {
            HttpResponse response = client.execute(request);
            if (response.getStatusLine().getStatusCode() != 200) {
                throw new RuntimeException("Failed to logout ST: " + response.getStatusLine());
            }
        }
    }

    private static CloseableHttpClient createInsecureHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException, KeyManagementException {

//        return HttpClients.createDefault();
        SSLContext sslContext = new SSLContextBuilder()
                .loadTrustMaterial(null, (certificate, authType) -> true)
                .build();

        SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);

        return HttpClients.custom()
                .setSSLSocketFactory(socketFactory)
                .build();
    }
}
复制代码

 4、CAS Service配置与管理

  示例中使用的url时 SERVICE_URL = "https://www.apereo.org"

  需要在cas服务的application.properties文件中配置 

# JSON 文件来初始化服务注册表(默认false)
cas.service-registry.init-from-json=true

  并且拷贝service的json文件,将WEB-INF/classes/services目录拷贝到services中

  

 5、Postman请求登录

  1、获取TGT

  

   2、获取ST

   

 

posted on   H__D  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Blazor Hybrid适配到HarmonyOS系统
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 解决跨域问题的这6种方案,真香!
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库
· 数据并发安全校验处理工具类
 
点击右上角即可分享
微信分享提示