从零开始搭建CAS

     背景

        对于每一个成年程序员来说,手动搭建一个CAS是一件十分有成就感的事。以前都是用公司现成的CAS服务,一点归属感都没有!今天,三十岁的我终于还是按捺不住,决定送给自己一份别样的成年礼物!没错,我觉得自己长大了,有足够的实力驾驭CAS了,不服来战!

     CAS介绍

        CAS,全称是Central Authentication Service,是一个开源的企业级单点登录系统,它为多个Web应用系统之间提供了一种可靠的单点登录方案。CAS主要通过浏览器重定向和代理票据机制实现用户的身份认证和授权,用户只需要在CAS系统中进行一次登录操作,就可以访问多个Web应用系统,而无需再次输入用户名和密码。

        CAS系统的核心是CAS Server和CAS Client,其中CAS Server负责用户的身份认证和授权,CAS Client则负责将用户的登录请求转发到CAS Server,并接收CAS Server返回的用户信息和授权信息,然后将用户信息和授权信息传递给Web应用系统进行验证和授权。

        CAS系统具有以下优点

                1)实现了跨应用的单点登录,用户只需要进行一次认证,即可访问多个Web应用系统。

                2)提供了可靠的身份认证和授权机制,保证了系统的安全性和稳定性。

                3)支持多种身份认证方式,例如用户名和密码、LDAP、CAS等。

                4)可以轻松地集成到现有的Web应用系统中,无需修改现有的应用程序代码。

                5)提供了可扩展的插件机制,可以根据需要扩展CAS系统的功能和特性。

        总之,CAS是一个成熟稳定的单点登录解决方案,广泛地应用于企业级应用系统中,为用户提供了方便快捷的身份认证和授权机制,提高了系统的安全性和可靠性。

        下面分几个场景和名词对CAS实现原理进行详细描述

        用户登录

        1、用户通过浏览器发送请求访问 CAS Client 资源,

        2、CAS Client 发现用户请求中未包含 ST 票据,将浏览器重定向到 CAS Server,此时 URL 中会携带名为 service 的参数,参数值是用户要访问的客户端资源地址

        3、CAS Server 对访问的用户是否携带 TGC 进行验证,若未携带则跳转到 CAS 统一的登录页面

        4、用户登录后,CAS Server 将浏览器重定向到之前 service 参数值指向的客户端地址(URL 的最后会增加 st 参数,CAS Client 可将 ST 保存起来),同时生成 TGC 写入浏览器中

        5、由于此次重定向携带了 ST,CAS Client 会向 CAS Server 发送验证请求

        6、CAS Server 验证通过,用户可以正常访问资源

        7、此时浏览器已与 CAS Client 建立会话,若 CAS Client 保存了 ST,后续请求通过会话即可调取 ST 并进行验证

        已登录用户访问其他资源

        1、用户访问未建立会话的 CAS Client 资源

        2、CAS Client 需要ST 进行验证,将浏览器重定向到 CAS Server

        3、用户访问 CAS Server,CAS Server 发现用户携带的有TGC,且根据TGC可以获取到 TGT,签发一个 ST,返回给用户浏览器并重定向到 CAS Client

        4、CAS Client 发现有 ST 去 CAS Server(CAS Client 可将 ST 保存起来) 验证,验证通过后,允许用户访问资源

        5、此时浏览器已与 CAS Client 建立会话,若 CAS Client 保存了 ST,后续请求通过会话即可调取 ST 并进行验证

        CAS SERVER

        CAS Server(CAS服务端)负责完成对用户的认证工作,完成与浏览器端的用户认证和CAS客户端的票据验证。

        CAS CLIENT

        CAS Client(CAS客户端)负责处理对受保护资源的访问请求,需要对请求方进行身份认证时,重定向到 CAS Server 进行认证。 CAS Client 与受保护的客户端应用部署在一起,以 Filter 方式保护受保护的资源。

        TICKET GRANGTING TICKET(TGT)

        TGT 是 CAS 为用户签发的登录票据,拥有了 TGT,用户就可以证明自己在CAS成功登录过。 TGT 封装了 Cookie 值以及此 Cookie 值对应的用户信息。用户在 CAS 认证成功后,CAS 生成 cookie(叫TGC),写入浏览器,同时生成一个 TGT 对象,放入自己的缓存,TGT 对象的 ID 就是 cookie 的值。 当 HTTP 再次请求到来时,如果传过来的有 CAS 生成的 cookie(TGC),则 CAS 以此 cookie 值为 key 查询缓存中有无 TGT,如果有,说明用户之前登录过,如果没有,则用户需要重新登录。

TICKET-GRANTING COOKIE(TGC)

        存放用户身份认证凭证的 cookie,在浏览器和 CAS Server 间通讯时使用,并且只能基于安全通道传输(Https),是 CAS Server 用来明确用户身份的凭证。

SERVICE TICKET(ST)

        服务票据,服务的惟一标识码 , 由 CAS Server 发出( Http 传送),用户访问 Service 时,Service 发现用户没有 ST,则要求用户去 CAS 获取 ST。CAS 协议规定ST只能使用一次,无论 Service Ticket 验证是否成功, Cas-Server 都会清除服务端缓存(MemoryCache)中的该 Ticket ,从而可以确保一个 Service Ticket 不被使用两次。只要成功验证一次,资源服务器就会缓存用户信息,从而不用再次验证了,ST也失去了它的作用。

     CAS实践

        在手动搭建CAS之前,先容我啰嗦几句。上文说到,TGC只能基于安全通道传输(Https),而且一般会用域名访问CAS服务,所以在搭建CAS的时候,一般会要求改hosts文件和生成SSLkey。但是SSL Key的生成十分繁琐,很多人因为在这个地方吃亏,一直没能把CAS搭起来,所以本次实践,咱们本着“先易后难”的思路,先把服务搭起来,再用数据库的数据替换静态用户,最后再生成SSL key,完整的来一遍。

      一、搭建最基本的CAS服务

        这一步是把网上提供的cas服务模板在本地用IDEA配置并启动起来,之所以要用IDEA,是为了有一个熟悉的环境来对配置信息息进行调整,监控项目启动。很多大佬不需要IDEA也能做到这些。

        1、下载cas-overlay-template,下载地址在这里 ,它相当于一个CAS的模板,而我们所谓的搭建CAS,就是用人家的模板对配置进行修改,调整成我们需要的样子(听起来一点都不高大上了)。需要说明的是,这个官方的地址很不稳定,经常访问不了,而且网上很多博客都推荐下载version 5.3版的,所以我也下的5.3,主打的就是一个听话,文中会提供我下载好的资源包。

        2、下载完之后解压,注意解压后的文件夹里有个build.cmd/build.sh文件,这个是内置的install cas服务包的脚本,Windows环境在该文件夹下进入cmd黑窗口,执行命令build.cmd run,即可完成cas-overlay-template的install工作, install成功之后会生成target文件。

        我第一次实践的时候没注意到这个,用了最笨的办法 mvn clean package,但因为没有配置MAVEN_HOME,所以失败了,大家不嫌麻烦的话也可以自己用命令install,殊途同归。

        2、将服务名改成cas-server,在该文件夹下创建/src/main/resources,/src/main/java目录,再用idea打开该项目,通过项目结构菜单修改两个文件夹的类型,如下:

        3、从target\cas\WEB-INF\classes中复制application.properties,log4j2.xml,services,粘贴到上一步创建的resources文件夹内,并修改log4j2.xml里的里的baseDir为一个固定的位置或者./cas/logs

        4、在/resources/application.properties里添加两行,注释三行,如下图所示,这一步是为了禁用SSL key,使得没有SSL key也可以访问CAS server

        5、在/resources/services/HTTPSandIMAPS-10000001.json文件夹下做如下修改(添加一个http,目的是让cas服务可以通过http访问)

        6、在idea中添加tomcat服务器,如下

        7、启动tomcat,系统会自动弹出以下网址,可用默认用户/密码”casuser/Mellon“进行登陆。至此,一个没配数据库的,没有SSL key的CAS服务就搭建成功了。

      二、CAS连接数据库

        按上面的步骤操作,虽然可以成功启动CAS,但是登陆CAS用的却还是静态的用户数据,正常使用CAS服务时,查询用户信息访问的是数据库里的数据,接下来咱们对配置进行调整,改用数据库的数据来登陆CAS。

        1、添加数据库依赖。我用的是达梦数据库,就添加了达梦数据库的依赖。注意下方截图,pom.xml里明确说明了在哪里添加依赖包,我当时没注意,自己建了个<dependencies>,然后调了好久都没连上数据库(被自己蠢哭了)。

                <dependency>
                    <groupId>org.apereo.cas</groupId>
                    <artifactId>cas-server-support-jdbc-drivers</artifactId>
                    <version>${cas.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.apereo.cas</groupId>
                    <artifactId>cas-server-support-jdbc</artifactId>
                    <version>${cas.version}</version>
                </dependency>
                <dependency>
                    <groupId>com.jdbc.dm</groupId>
                    <artifactId>DmJdbcDriver18</artifactId>
                    <version>1.0</version>
                </dependency>

        2、在application.properties添加数据库配置,同时注释掉默认用户

        #cas.authn.accept.users=casuser::Mellon
        如下:
#cas.authn.accept.users=casuser::Mellon
#查询用户信息的sql
cas.authn.jdbc.query[0].sql=select password from sys_user where userCode=? and isDelete = 0
#指定密码的字段名
cas.authn.jdbc.query[0].fieldPassword=password
#指定过期字段,1为过期,若该字段为1,说明账户过期,该配置非必须
#cas.authn.jdbc.query[0].fieldExpired=expired
#指定不可用字段,若该字段为1,说明账户不可用,需要修改密码
#cas.authn.jdbc.query[0].fieldDisabled=disabled
#数据库方言,hiberate
#cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect
#数据库驱动
cas.authn.jdbc.query[0].driverClass=dm.jdbc.driver.DmDriver
#数据库连接url
cas.authn.jdbc.query[0].url=jdbc:dm://192.168.5.97:5238/DEV_COMMON
#数据库用户名
cas.authn.jdbc.query[0].user=DEV_COMMON
#数据库密码
cas.authn.jdbc.query[0].password=leixiyueqi

#默认加密策略,通过encodingAlgorithm来指定算法,默认NONE不加密
cas.authn.jdbc.query[0].passwordEncoder.type=DEFAULT
cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8
#加密算法为MD5
cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=MD5

        这里也附上建表语句和sql:

drop table if exists sys_user;
CREATE TABLE sys_user(
    id VARCHAR2(32) NOT NULL,
    userCode VARCHAR2(100),
    password VARCHAR2(255),
    userName VARCHAR2(100),
    accountExpired VARCHAR2(5),
    passExpired VARCHAR2(5),
    createrId VARCHAR2(50) NOT NULL,
    createrName VARCHAR2(100) NOT NULL,
    createTime Datetime NOT NULL,
    modifierId VARCHAR2(50),
    modifierName VARCHAR2(100),
    modifyTime Datetime,
    isDelete INTEGER NOT NULL DEFAULT  (0),
    PRIMARY KEY (id)
);

COMMENT ON TABLE sys_user IS '系统用户表';
COMMENT ON COLUMN sys_user.id IS '主键ID';
COMMENT ON COLUMN sys_user.userCode IS '用户账号';
COMMENT ON COLUMN sys_user.password IS '登陆密码';
COMMENT ON COLUMN sys_user.userName IS '用户名称';
COMMENT ON COLUMN sys_user.accountExpired IS '账号过期标记';
COMMENT ON COLUMN sys_user.passExpired IS '密码过期标记';
COMMENT ON COLUMN sys_user.createrId IS '创建人ID';
COMMENT ON COLUMN sys_user.createrName IS '创建人';
COMMENT ON COLUMN sys_user.createTime IS '创建时间';
COMMENT ON COLUMN sys_user.modifierId IS '更新人ID';
COMMENT ON COLUMN sys_user.modifierName IS '更新人';
COMMENT ON COLUMN sys_user.modifyTime IS '更新时间';
COMMENT ON COLUMN sys_user.isDelete IS '是否删除';

--该密码 e10adc3949ba59abbe56e057f20f883e 是123456经过MD5加密后的结果
insert into sys_user(id,userCode, password, userName,createrId, createrName,createTime, isDelete) values(sys_guid, 'leixi','e10adc3949ba59abbe56e057f20f883e', '雷袭','system','系统',sysdate, 0);

        3、重新启动服务,用leixi/123456登陆系统,同样可以登陆。

      三、生成SSL key

        上文说了,从安全角度考虑,访问CAS服务必须要使用https和域名,那么怎么在本地使用https呢?我们需要用到SSL key,下面先简单的介绍下SSL key。

        SSL(Secure Sockets Layer)是一种用于保护数据传输安全的协议。在 SSL 协议中,通过使用公钥加密和私钥解密的方式来实现数据传输的加密和解密。SSL 通常使用数字证书来验证身份和建立加密连接。数字证书包含公钥和私钥,其中公钥用于加密数据,私钥用于解密数据。数字证书通常由可信的第三方机构(如 CA 机构)颁发和管理。在 SSL 中,为了保护私钥的安全,通常将私钥存储在服务器的安全存储区域中,并使用密码进行保护。

        SSL 协议的使用需要 SSL 证书的支持。在安装 SSL 证书时,需要提供证书的公钥和私钥,以便服务器可以使用它们来建立安全连接。SSL key 是 SSL 证书中的私钥,用于解密客户端发送的加密数据,保护数据传输的安全。

        本地生成SSL key的步骤如下:

         1、在C:\Windows\System32\drivers\etc\hosts文件中添加以下内容:127.0.0.1 cas.server.home

        2、找到本地的jdk路径,在bin文件夹下打开cmd窗口,执行以下命令:keytool -genkey -alias tomcat -keyalg RSA -validity 3650 -keystore D:/server/tomcat.keystore 

        -alias tomcat :表示秘钥库的别名是tomcat,实际操作都用别名识别,所以这个参数很重要。
        -validity 3650 : 表示证书有效期10年。

        注意,名字姓式和组织单位名称要设成域名 cas.server.com,其他的直接回车,最后输入“y” 。

        3、同样的在那个路径下,输入命令查看证书keytool -list -keystore D:/server/tomcat.keystore(该步骤不执行也没影响,属于第2步的验证)

        4、根据keystore生成cer文件,导出证书以供客户端信任 keytool -export -alias tomcat -file D:/server/tomcat.cer -keystore D:/server/tomcat.keystore -validity 3650

        5、将cer文件到导入到jdk的Key Store,这样,该证书就被java服务信任了。

        keytool -import -alias tomcat -keystore ..\jre\lib\security\cacerts -file D:/server/tomcat.cer

        这一步要格外说明下,这里有个大坑。我之前执行的命令是keytool -import -alias tomcat -keystore cacerts -file D:/server/tomcat.cer。但这个命令会在\[jdkfile]\bin下生成一个cacerts文件,并把证cer文件导入到该cacerts文件下面。其实jdk是从\[jdkfile]\jre\lib\security\cacerts文件中读取受信任的证书的,这会导致cas在启动时反复的报错 :PKIX path building failed。在网上搜了很多资料,都说是证书有问题,没有正确的导入证书,实际上是证书导错了地方,这个是吃了马虎大意的亏。

        (这里也附上其他的命令,以备不时之需:

        删除授权证书 keytool -delete -alias tomcat -keystore ..\jre\lib\security\cacerts

        查看授权证书: keytool -list -v -keystore cacerts)

         6. Tomcat配置使用刚才生成的证书,在tomcat的\conf\server.xml里找到以下Connector port="8443"等内容,作以下调整:

	<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="200" SSLEnabled="true" scheme="https"
           secure="true" clientAuth="false" sslProtocol="TLS"
           keystoreFile="d:/server/tomcat.keystore"
           keystorePass="changeit"/>
<!-- keystoreFile 配置的是上文中生成的keystore的路径,keystorePass配置的是我生成证书的密钥-->

        7、在application.properties里将cas.tgc.secure=false注释,再添加以下内容

        8、重启电脑,激活hosts的更改,然后重新启动CAS服务,访问http://cas.server.home:8080/cas/login 和 https://server.cas.com:8443/cas/login,可以进行正常的登陆。至此,一个CAS服务器才算是完完整整的搭起来了

CAS之殇

        好不容易搭建起了cas,我在网上一搜,却发现主流的博客里已经很少再用CAS了,那么为什么它会淡出行业的视野呢?这就得说下“三方认证”和“四方认证”了。

        前文已经介绍了 CAS 认证的过程,可以看出 CAS 的认证基于会话(即浏览器与服务器之间的 Session),因此终端、CAS 客户端与 CAS 服务端会组成一个三方的认证系统。登录之后的浏览器会在 CAS Server 的域名下存放 cookie,用于浏览器和 CAS Server 之间验证是否登录;而在访问 CAS Client 资源时则会在 Client 的域名下存放一个 cookie,用于下次访问资源时调取 ST 与 CAS Server 进行验证。

        现在问题出现了!当技术不断革新,Springboot取代springMVC,前端与后端分离时,原本的 CAS Client 就不再是一方了,而是变成了两方,于是三方认证也成了四方认证。 如果是单纯的变成了两方也并没有离开 CAS 的认证框架,无非是多一个 CAS Client 罢了,然而前端常用的 Ajax 请求恰好无法处理 CAS 中最常见的重定向操作。这样一来,包括首次登录、登录成功后返回 ST、认证登录等一系列的逻辑似乎都没有办法继续进行了。因此,CAS不再适用于现如今的前后端分离的主流框架,渐渐的也就被新的技术淘汰了。

        但是,学习要有始有终,今天我学会了搭建CAS Server,下一次我势必得学会Cas Client的搭建,即便它是一个过时的技术,但学习它、了解它,仍然会对我掌握其他知识有一定的帮助。下一章,咱们敬请期待:SpringBoot整合Cas服务。

      致谢

        为了完成本次的实践,我找了很多的资料,也参考了许多大佬的文章,以下是我觉得对我帮助很大的博客,感谢大佬们的指路,雷袭感激不尽。

        CAS(一)搭建CAS - server服务器_cas-server-webapp-6.1.0.war-CSDN博客

        cas5.3.2单点登录-骨架搭建(一)_cas5.3.2 casutil-CSDN博客

        springboot实现CAS的server服务器端的搭建,并实现链接mysql数据库,自定义加密算法_cas-overlay-template-5.3 access denied-CSDN博客

        Cas5.3服务器集成DM8 达梦数据库_cas 适配达梦数据库-CSDN博客

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值