CAS5.3服务器搭建与客户端整合SpringBoot,cas服务器返回用户名以及更多的数据信息。


CAS5.3服务器搭建与客户端整合SpringBoot以及踩坑笔记
cas服务器的搭建
  1. 导出证书(1和2步骤是找了课程,随便写了一下存记录,不过对于自己测试不投入使用应该不影响)

    1. C:\Users\Ddlm2>keytool -genkey -alias testcas -keystore D:/testcas -storepass 123456 -keyalg RSA -validity 3650
    2. 您的名字与姓氏是什么?
    3. [Unknown]: test
    4. 您的组织单位名称是什么?
    5. [Unknown]: test
    6. 您的组织名称是什么?
    7. [Unknown]: test
    8. 您所在的城市或区域名称是什么?
    9. [Unknown]: test
    10. 您所在的省/市/自治区名称是什么?
    11. [Unknown]: test
    12. 该单位的双字母国家/地区代码是什么?
    13. [Unknown]: test
    14. CN=test, OU=test, O=test, L=test, ST=test, C=test是否正确?
    15. [否]: Y
    16. 输入 <testcas> 的密钥口令
    17. (如果和密钥库口令相同, 按回车):
    18. 再次输入新口令:
    19. Warning:
    20. JKS 密钥库使用专用格式。建议使用 "keytool -importkeystore -srckeystore D:/testcas -destkeystore D:/testcas -deststoretype pkcs12" 移到行业标准格式 PKCS12
    21. C:\Users\Ddlm2>keytool -genkey -alias testcas -keystore D:/testcas -storepass 123456 -keyalg RSA -validity 3650 -export -trustcacerts -file D:/testcas.cer
    22. 存储在文件 <D:/testcas.cer> 中的证书
    23. Warning:
    24. JKS 密钥库使用专用格式。建议使用 "keytool -importkeystore -srckeystore D:/testcas -destkeystore D:/testcas -deststoretype pkcs12" 移到行业标准格式 PKCS12
  2. 导入jdk的证书库

    1. C:\Users\Ddlm2>keytool -import -trustcacerts -alias testcas -file D:/testcas.cer
    2. 输入密钥库口令:
    3. 再次输入新口令:
    4. 所有者: CN=test, OU=test, O=test, L=test, ST=test, C=test
    5. 发布者: CN=test, OU=test, O=test, L=test, ST=test, C=test
    6. 序列号: 429f9b95
    7. 生效时间: Fri Aug 13 11:15:22 CST 2021, 失效时间: Mon Aug 11 11:15:22 CST 2031
    8. 证书指纹:
    9. SHA1: 3A:20:B4:25:12:96:6E:EB:F7:15:15:BE:11:A7:C5:66:60:25:D6:A8
    10. SHA256: 06:80:FC:34:63:27:20:ED:6E:74:CB:51:2B:5B:86:E0:70:C2:CD:65:36:46:52:13:25:0A:B4:9B:7F:67:31:B7
    11. 签名算法名称: SHA256withRSA
    12. 主体公共密钥算法: 2048 RSA 密钥
    13. 版本: 3
    14. 扩展:
    15. #1: ObjectId: 2.5.29.14 Criticality=false
    16. SubjectKeyIdentifier [
    17. KeyIdentifier [
    18. 0000: 24 05 3F B0 42 A4 02 84 70 D1 F2 09 4A AB D8 93 $.?.B...p...J...
    19. 0010: 8B 29 85 BB .)..
    20. ]
    21. ]
    22. 是否信任此证书? [否]: y
    23. 证书已添加到密钥库中

    注:应该是在webapps\cas\WEB-INF\classes中的application.properties中配置(开头7行左右)

    不过自己测试,只会提示密码泄露不安全什么的,无大碍。

  3. 下载 cas server 安装包,这里使用的是5.3。下面的链接都可以使用

    1. https://github.com/apereo/cas-overlay-template/tree/5.3
    2. ----------------------------------------
    3. https://wwa.lanzoui.com/b010pvygd
    4. 密码:casserver
  4. 打war包。 安装maven的环境变量(或者导入idea打包),在cas-overlay-template-5.3目录打开cmd命令行使用mvn package进行打包,会在target目录下出现cas.war文件,

  5. 部署tomcat。 将本地tomcat服务器拷贝出来一份,作为cas服务器,将war包复制到webapps下面。运行tomcat,war包会自动解压到car文件夹中。

    注:如果cas使用5以上,tomcat必须8以上。

  6. 端口映射。 在tomcat目录下的conf目录下的server.xml中添加

    1. <Connector port="8332" protocol="HTTP/1.1"
    2. connectionTimeout="20000"
    3. redirectPort="8443" />
    4. <!-- 意为将8332接口转到8443接口 -->
    5. <!-- 8332是对外的,那么8443呢,cas默认端口就是8443,applicaion.properties中的第5行左右 -->

    注:主要为了防止端口号冲突,都可以任意修改。

  7. 添加http协议。 webapps\cas\WEB-INF\classes\services下的HTTPSandIMAPS-10000001.json的第三行修改成"serviceId" : "^(https|http|imaps)://.*",使其接受http协议。

  8. 也可以自定义用户名。 webapps\cas\WEB-INF\classes下的application.properties 最后那里

    cas.authn.accept.users=casuser::Mellon

    是默认的用户名和密码,可以修改为自己喜欢的。

  9. 重启tomcat, 访问localhost:8332/cas/login输入7步骤中的账号密码进行测试。


接下来整理,springboot整合cas client。cas服务器端返回数据在下面。


SpringBoot整合cas客户端
  1. 新建maven或者springboot项目都可以,打开pom文件添加依赖。

    1. <dependencies>
    2. <!-- cas的客户端 -->
    3. <dependency>
    4. <groupId>net.unicon.cas</groupId>
    5. <artifactId>cas-client-autoconfig-support</artifactId>
    6. <version>2.2.0-GA</version>
    7. <exclusions>
    8. <exclusion>
    9. <groupId>org.jasig.cas.client</groupId>
    10. <artifactId>cas-client-core</artifactId>
    11. </exclusion>
    12. </exclusions>
    13. </dependency>
    14. <!-- 使用更高版本的cas-client-core -->
    15. <dependency>
    16. <groupId>org.jasig.cas.client</groupId>
    17. <artifactId>cas-client-core</artifactId>
    18. <version>3.5.0</version>
    19. </dependency>
    20. <!-- 故意降的版本 -->
    21. <dependency>
    22. <groupId>org.springframework.boot</groupId>
    23. <artifactId>spring-boot-starter-web</artifactId>
    24. <version>2.1.3.RELEASE</version>
    25. </dependency>
    26. </dependencies>

    注:若启动时候报错,且去掉cas相关东西又可以正常启动。可以尝试降一下你自己的springboot版本。

  2. 添加启动类,切记@EnableCasClient

    1. import net.unicon.cas.client.configuration.EnableCasClient;
    2. import org.springframework.boot.SpringApplication;
    3. import org.springframework.boot.autoconfigure.SpringBootApplication;
    4. /**
    5. * @author ddlm
    6. * @date 2021/08/17 10:53
    7. */
    8. @EnableCasClient
    9. @SpringBootApplication
    10. public class CASClientOne {
    11. public static void main(String[] args) {
    12. SpringApplication.run(CASClientOne.class, args);
    13. }
    14. }
  3. 添加配置,这里使用的yml,properties就是:变.和=而已。

    1. server:
    2. port: 9101
    3. cas:
    4. # cas服务器端的地址和端口,注意端口号。
    5. server-url-prefix: http://localhost:8332/cas
    6. server-login-url: http://localhost:8332/cas/login
    7. # 本地的地址,用于回调回来
    8. client-host-url: http://localhost:9101
    9. # 需要拦截的地址(所有为"/*"),可配置数组
    10. authentication-url-patterns:
    11. - "/auth/login"
    12. - "/auth/createOrder"
    13. validation-type: CAS3

    注:拦截的接口是个例子。因为使用场景场景不同:全由cas控制或者只需要登录在自己项目控制。

    如果服务端不需要关,只需要使用cas实现单点登录,且获取数据,如果从session中获取,需要配置中开启一下:
    cas: use-session: true,对应获取数据就request.getSession().getAttribute("key");

  4. 随便写个接口测试。

    1. @RestController
    2. public class TestController {
    3. @RequestMapping("/testFirst")
    4. public String TestMethod() {
    5. return "This is First Method.";
    6. }
    7. }

    注:确保url在配置中的拦截范围内。

  5. 为了方便对比,再新建一个项目,步骤一致,起码接口名、端口名和返回内容修改一下。

  6. 启动两个项目,访问第一个项目中的接口,需要登录,登录后。

  7. 访问第二个项目的接口,此时不需要登录即为成功。

  8. 扩展: 一些博客中,结合了拦截器进行匹配,这个看需要进行添加,主要是可以忽略接口,加几层一般都可以避免,如果使用过滤器注意与配置的交集。

    1. @Configuration
    2. public class CASConfig {
    3. @Value("${cas.server-url-prefix}")
    4. private String serverUrlPrefix;
    5. @Value("${cas.server-login-url}")
    6. private String serverLoginUrl;
    7. @Value("${cas.client-host-url}")
    8. private String clientHostUrl;
    9. @Value("${ignore-host-url}")
    10. private String ignoreHostUrl;
    11. /**
    12. * 授权过滤器
    13. */
    14. @Bean
    15. public FilterRegistrationBean filterAuthenticationRegistration() {
    16. FilterRegistrationBean registration = new FilterRegistrationBean();
    17. registration.setFilter(new AuthenticationFilter());
    18. // 设定匹配的路径
    19. registration.addUrlPatterns("/*");
    20. Map<String,String> initParameters = new HashMap<>();
    21. initParameters.put("casServerLoginUrl", serverUrlPrefix);
    22. initParameters.put("serverName", clientHostUrl);
    23. //忽略的url,"|"分隔多个url
    24. initParameters.put("ignorePattern", ignoreHostUrl);
    25. registration.setInitParameters(initParameters);
    26. // 设定加载的顺序
    27. registration.setOrder(1);
    28. return registration;
    29. }
    30. }

    其中ignore-host-url需要另外在yml中配置。


接下来配置cas服务器从数据库中获取用户名和密码,并返回该人员所有信息(只是测试使用)

cas服务器连接数据库
  1. 获取登录名。为什么多返回更多内容呢,因为用户名默认会返回,这里介绍获取用户名的三种方法。

    1. request.getRemoteUser();
    2. ((Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION)).getPrincipal().getName();
    3. 第二步不getName(),getAttributes();在得到的集合中去get("username"),大概,可以打印出来找一下。

    注:从request中能get到的都get过来了,然后转成json输出找到的…

  2. CAS服务器配置连接数据库。

    我测试时候是重新打包的,也可以参考这位大佬的博客tomcat8搭建cas服务器,使用MYSQL数据库

    或者这位大佬的:cas5.3.1 从搭建到连接mysql(简而优美),是直接复制jar包进来,不需要重新打包的。

    添加需要访问数据库的依赖,在cas-overlay-template-5.3/pom.xml

    1. <dependency>
    2. <groupId>org.apereo.cas</groupId>
    3. <artifactId>cas-server-support-jdbc</artifactId>
    4. <version>${cas.version}</version>
    5. </dependency>
    6. <dependency>
    7. <groupId>org.apereo.cas</groupId>
    8. <artifactId>cas-server-support-jdbc-drivers</artifactId>
    9. <version>${cas.version}</version>
    10. </dependency>
    11. <dependency>
    12. <groupId>mysql</groupId>
    13. <artifactId>mysql-connector-java</artifactId>
    14. <!-- 与数据库版本一致 -->
    15. <version>8.0.23</version>
    16. </dependency>

    注:切记最后面那个版本号一定一定一定要跟自己mysql的版本一致。可百度查看如何查看MySQL版本。

    ​ 小版本号也要保证一致!!!

  3. 打包,部署,重新按照服务器的部署修改一下。

  4. 修改 webapps\cas\WEB-INF\classes下的application.properties最后部分,注释掉默认或者自定义的账号密码:
    # cas.authn.accept.users=casuser::Mellon

    添加:

    1. cas.authn.jdbc.query[0].url=jdbc:mysql://localhost:3306/cas_server_demo?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
    2. cas.authn.jdbc.query[0].principalAttributeList=id,username,password,stunumber,stuclass
    3. cas.authn.jdbc.query[0].user=root
    4. cas.authn.jdbc.query[0].password=123456
    5. cas.authn.jdbc.query[0].sql=select id,username,password,stu_number as stuNumber,stu_class as stuClass from student where username=?
    6. cas.authn.jdbc.query[0].fieldPassword=password
    7. # cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver
    8. cas.authn.jdbc.query[0].driverClass=com.mysql.cj.jdbc.Driver
    9. # 忽略https安全协议,使用 HTTP 协议
    10. cas.tgc.secure=false
    11. # 是否开启json识别功能,默认为false
    12. cas.serviceRegistry.initFromJson=true
    13. # 指明路径
    14. cas.serviceRegistry.json.location=classpath:/services

    注:

    1. principalAttributeList中是返回的字段名,如果想要定义别名,需要在sql中使用as重新命名。
    2. 注意mysql版本号与driverClass的对应。
    3. 未涉及密码加密。
    4. 当不需要定义别名时候,sql可以直接select *
    5. 见网上说数据库字段名带下划线返回不回来,经过测试可以返回,如果失败定义别名可解决。
  5. 修改webapps\cas\WEB-INF\classes\services\HTTPSandIMAPS-10000001.json,最后添加:

    1. {
    2. "@class" : "org.apereo.cas.services.RegexRegisteredService",
    3. "serviceId" : "^(https|http|imaps)://.*",
    4. "name" : "HTTPS and IMAPS",
    5. "id" : 10000001,
    6. "description" : "This service definition authorizes all application urls that support HTTPS and IMAPS protocols.",
    7. "evaluationOrder" : 10000,
    8. "attributeReleasePolicy" : {
    9. "@class" : "org.apereo.cas.services.ReturnAllAttributeReleasePolicy"
    10. }
    11. }

    添加attributeReleasePolicy,注意json格式,上面要添加,

  6. 准备MySQL数据库数据

    1. /*
    2. Navicat Premium Data Transfer
    3. Source Server : localMysql
    4. Source Server Type : MySQL
    5. Source Server Version : 80023
    6. Source Host : localhost:3306
    7. Source Schema : cas_server_demo
    8. Target Server Type : MySQL
    9. Target Server Version : 80023
    10. File Encoding : 65001
    11. Date: 17/08/2021 13:56:44
    12. */
    13. SET NAMES utf8mb4;
    14. SET FOREIGN_KEY_CHECKS = 0;
    15. -- ----------------------------
    16. -- Table structure for student
    17. -- ----------------------------
    18. DROP TABLE IF EXISTS `student`;
    19. CREATE TABLE `student` (
    20. `id` int(0) NOT NULL AUTO_INCREMENT,
    21. `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
    22. `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
    23. `stu_number` int(0) NULL DEFAULT NULL,
    24. `stu_class` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
    25. PRIMARY KEY (`id`) USING BTREE
    26. ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
    27. -- ----------------------------
    28. -- Records of student
    29. -- ----------------------------
    30. INSERT INTO `student` VALUES (1, 'admin', 'admin', 222222424, '234');
    31. INSERT INTO `student` VALUES (2, 'test1', 'test1', 123454321, '235');
    32. SET FOREIGN_KEY_CHECKS = 1;
  7. 重启tomcat,注意启动日志。

  8. springboot cas client取数据,我整理了一个简易工具类。

    1. import org.jasig.cas.client.authentication.AttributePrincipal;
    2. import org.jasig.cas.client.util.AbstractCasFilter;
    3. import org.jasig.cas.client.validation.Assertion;
    4. import javax.servlet.http.HttpServletRequest;
    5. import java.util.Map;
    6. public class CASUtil {
    7. private static HttpServletRequest request;
    8. /**
    9. * 从cas中获取用户名
    10. *
    11. * @param request Http请求
    12. * @return 登录cas服务器的用户名
    13. */
    14. public static String getAccountNameFromCas(HttpServletRequest request) {
    15. CASUtil.request = request;
    16. Assertion assertion = (Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
    17. if (assertion != null) {
    18. AttributePrincipal principal = assertion.getPrincipal();
    19. return principal == null ? null : principal.getName();
    20. } else {
    21. return null;
    22. }
    23. }
    24. /**
    25. * 从cas返回值中获取内容
    26. *
    27. * @param request Http 请求
    28. * @param attr 需要获取值的键名
    29. * @return 键名attr对应的值
    30. */
    31. public static String getAttributeFromCas(HttpServletRequest request, String attr) {
    32. CASUtil.request = request;
    33. Assertion assertion = (Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
    34. if (assertion != null) {
    35. AttributePrincipal principal = assertion.getPrincipal();
    36. // 一般不会为空,因为有attributes
    37. if(principal != null) {
    38. Object obj = principal.getAttributes().get(attr);
    39. return obj == null ? null : obj.toString();
    40. }
    41. }
    42. return null;
    43. }
    44. }
  9. 至此,完毕。

  10. 整理要点

    1. cas服务器
      1. 端口(server.xml)
      2. 连接数据库(application.properties)
      3. 修改json配置文件(HTTPSandIMAPS-10000001.json)
      4. 连接数据库依赖的驱动版本号
      5. cas与tomcat版本
    2. cas客户端
      1. 依赖版本号(cas和springboot的)
      2. @EnableCasClient注解
      3. 配置文件中的cas服务器地址、本机地址和需要验证的接口
      4. 通过request获取即可
  11. 当用户名登录不上时候,查看cas服务器命令行是否有异常。

  12. 参考:

    1. SpringBoot 搭建CAS 客户端 和CAS 服务端
    2. 从零开始部署CAS服务器
    3. cas5.3.1 从搭建到连接mysql(简而优美)
    4. cas服务端搭建
    5. CASServer5.3.* 返回多值及Spring Boot集成获取用户属性数据

版权声明:本文为Ddlm2wxm原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/Ddlm2wxm/p/15152358.html