目录
5.CAS——Central Authentication Service(中央认证服务)
二、CAS5.3服务端搭建——放tomcat(不导入idea)
生成秘钥库和证书并把证书导入jdk证书库(这里生成证书的参数设置有误导致在第五步客户端访问服务端时出现问题(这里没有影响),正确的步骤请看第五步!)
修改\webapps\cas\WEB-INF\classes目录下的application.properties文件
三、CAS5.3服务端搭建——导入idea(不放tomcat)
3.HTTP方式——配置cas数据源——用户信息从Mysql取(有些步骤之前已完成)
4.HTTPS方式——搭建本地HTTPS服务(有些步骤之前已完成)
修改application.properties,cas.tgc.secure设为true编辑
修改application.properties,放开注释并修改值(不修改FileNotFoundException:)
[之前讲解HTTP方式时已经配置完成]-配置数据源和密码加密
[配置失败!--忽略这一步]——IDEA中配置独立tomcat代替build.cmd run启动
1.生成秘钥库和证书并把证书导入jdk证书库(上面配置有误,这里是正确配置)
定义好认证中心域名,下面配置需要保持一致(正是之前生成证书时存在的问题)
2.更新服务端的application.properties和hosts文件
一、前言
1.SSO
SSO单点登录是把若干子系统的登录模块抽离整合到专门的认证系统,统一进行登录管理,主要实现的是:用户访问单个子系统,该子系统检测到未登录就会重定向到认证中心进行登录,登录成功后,用户在以后一个时间段内在同一个客户端(浏览器)访问其它子系统就不需要再登录;同时某一子系统退出登录时,认证中心也退出登录。
2.Sso一个实现案例的图示
3.sso和第三方登录区别
单点登录应用于同一公司的若干系统之间。
4.全局会话
全局会话是若干客户端通过浏览器和单一认证中心之间建立并保持的会话,当某一客户端重定向访问认证中心进行首次登录操作时,浏览器地址栏会由客户端的域名变为认证中心的域名,相当于浏览器发起了一次访问认证中心的请求并建立起全局会话,此时全局会话的JSESSIONID会自动地被浏览器保存在认证中心域名下的cookie中。后续其它客户端再在此台浏览器重定向访问认证中心时,由于浏览器地址栏请求的域名都是认证中心的域名,浏览器会自动带上该域名的cookie访问认证中心,由于cookie中jsessionid相同的,所以是一个会话,称为全局会话,实现了session共享。
浏览器会携带哪些cookie放到请求头呢?
从url获取域名(不含port)tieba.baidu.com,获取本地cookie列表中所有域名设置为tieba.baidu.com的cookie 以及 本地cookie列表中所有域名设置为tieba.baidu.com的父域名baidu.com的cookie。
5.CAS——Central Authentication Service(中央认证服务)
CAS是耶鲁大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法。
第5步的验证只需要拿到票据后的第一次请求需要进行(除非创建的局部会话和cookie失效了)。
特点
1、开源的企业级单点登录解决方案。
2、CAS Server 为需要独立部署的 Web 应用(独占一台web容器)。
3、CAS Client 支持非常多的客户端(这里指单点登录系统中的各个 Web 应用),包括 Java, .Net, PHP, Perl, Apache, uPortal, Ruby 等。
4、CAS属于Apache 2.0许可证(Apache2.0 开源协议对使用,复制,修改,商用不做过多限制,但必须包含原著的License信息),允许代码修改,再发布(作为开源或商业软件)。
版本
6.0 及以上需要jdk11,如果你是jdk8,最高只能用5.3版本
5.3 以下版本的是[maven]工程,6.0以上改成[gradle]工程了
有web版本、maven版本、gradle版本三种,本文演示的5.3是maven版本
社区实践表明,建议CAS 部署在至少8GB双核 3.00Ghz 的处理器上。如果日志保存在该服务器上,则还需要足够的磁盘空间(最好是SSD)来存放日志
下载
界面下载
GitHub - apereo/cas-overlay-template at 5.3
GIT下载
可以下载master,然后再进行切换
git clone https://github.com/apereo/cas-overlay-template.git
也可以只下载5.3版本的分支
git clone -b 5.3 https://github.com/apereo/cas-overlay-template.git
请求方式
CAS默认使用的是HTTPS协议,如果使用HTTPS协议需要SSL安全证书(需向特定的机构申请和购买),也可以自己生成证书搭建本地https服务 。在开发测试阶段可修改配置使用HTTP协议。
如果不去除https认证而使用http请求会提示未认证授权的服务:
二、CAS5.3服务端搭建——放tomcat(不导入idea)
1.环境准备
cas server必须独立部署在一台web容器中(独占一个tomcat服务器),准备一个tomcat放在E:\2kc-projectSets\1AllCompany\01Gener\gener010-CAS目录下。
在E:\2kc-projectSets\1AllCompany\01Gener\gener010-CAS目录保存有从github下载的cas压缩包cas-overlay-template-5.3.zip,解压缩并进入解压后的文件夹,进入到E:\2kc-projectSets\1AllCompany\01Gener\gener010-CAS\cas-overlay-template-5.3\cas-overlay-template-5.3中,在此处执行cmd命令mvn clean package(使用builde.cmd run也可以),会生成target文件夹,内部含有cas.war文件。
复制cas.war到tomcat的webapps文件夹下并解压,解压完成后删除原压缩包。
配置CAS日志地址
找到E:\2kc-projectSets\1AllCompany\01Gener\gener010-CAS\apache-tomcat-9.0.34-windows-x64\apache-tomcat-9.0.34\webapps\cas\WEB-INF\classes下的log4j2.xml
在这里可以修改日志存储目录等配置,windows下不修改会在当前盘符下自动新建此目录
2.HTTP方式
修改\webapps\cas\WEB-INF\classes\services目录下的HTTPSandIMAPS-10000001.json文件,把原来的serviceId内容改成如下
"serviceId" : "^(https|http|imaps)://.*",
修改\webapps\cas\WEB-INF\classes目录下的application.properties文件,最后追加
#霍其旺新添加的内容 #false忽略https安全协议使用HTTP协议;true使用https安全协议; cas.tgc.secure=false #是否开启json识别功能,默认为false cas.serviceRegistry.initFromJson=true
默认用户名密码配置也在application.properties文件中(密码大小写敏感)
# 可以修改登录用户名密码,默认casuser::Mellon
cas.authn.accept.users=casuser::Mellon
启动tomcat,访问http://localhost:8080/cas/login,登陆成功:
3.HTTPS方式——搭建本地HTTPS服务
生成秘钥库和证书并把证书导入jdk证书库(这里生成证书的参数设置有误导致在第五步客户端访问服务端时出现问题(这里没有影响),正确的步骤请看第五步!)
在第五步客户端访问服务端时出现的问题第五步不再作记录,这里记录一下出现的问题:
客户端:
页面:
1.生成秘钥库
cmd执行
keytool -genkey -alias skl -keyalg RSA -keystore E:/2kc-projectSets/1AllCompany/01Gener/gener010-CAS/secretkey #-alias指定密钥库别名为skl #-keyalg指定加密算法 #最后的路径的末尾的secretkey是将要生成的密钥库文件 -alias 产生别名 -keystore 指定密钥库的名称(产生的各类信息将不在.keystore文件中) -keyalg 指定密钥的算法 (如 RSA DSA(如果不指定默认采用DSA)) -validity 指定创建的证书有效期多少天 -keysize 指定密钥长度 -storepass 指定密钥库的密码(获取keystore信息所需的密码) -keypass 指定别名条目的密码(私钥的密码) -dname 指定证书拥有者信息 例如: "CN=名字与姓氏,OU=组织单位名称,O=组织名称,L=城市或区域名称,ST=州或省份名称,C=单位的两字母国家代码" -list 显示密钥库中的证书信息 -v 显示密钥库中的证书详细信息 -export 将别名指定的证书导出到文件 -file 参数指定导出到文件的文件名 -delete 删除密钥库中某条目 -printcert 查看导出的证书信息 -keypasswd 修改密钥库中指定条目口令 -storepasswd 修改keystore口令 -import 将已签名数字证书导入密钥库
在E:\2kc-projectSets\1AllCompany\01Gener\gener010-CAS下生成secretkey秘钥库:
2.基于秘钥库生成证书
cmd执行
keytool -export -trustcacerts -alias skl -file E:/2kc-projectSets/1AllCompany/01Gener/gener010-CAS/secretkey.cer -keystore E:/2kc-projectSets/1AllCompany/01Gener/gener010-CAS/secretkey #前面的路径是要导出证书的位置和证书名称 #后面的路径是之前密钥库的路径,别名和秘钥库别名skl保持一致
在E:\2kc-projectSets\1AllCompany\01Gener\gener010-CAS下生成secretkey.cer证书:
3.把证书导入到JDK证书库
cmd执行
keytool -import -trustcacerts -alias skl -file E:/2kc-projectSets/1AllCompany/01Gener/gener010-CAS/secretkey.cer -keystore "E:/1kc-devtools/jdk/jre/lib/security/cacerts" #别名和前面的别名skl保持一致即可 #前面路径是前面生成的证书的位置,后面是个人jdk中cacerts的所在目录
补充:若证书别名skl已存在会不能重复添加,如何删除jdk证书库的旧证书?
keytool -delete -alias skl -keystore E:/1kc-devtools/jdk/jre/lib/security/cacerts #skl是已存在证书的别名,E:/1kc-devtools/jdk/jre/lib/security/cacerts是个人jdk的cacerts路径 #输入口令:changeit,回车,ok。
关键——修改tomcat的server.xml配置
在96行添加(配置的端口为https默认端口443,访问时可以省略不写如同http的80端口一样),注意配置的值是先前的秘钥库相关信息
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="E:\2kc-projectSets\1AllCompany\01Gener\gener010-CAS\secretkey"
keystorePass="123456" /><!--秘钥库位置--><!--秘钥库口令-->
注释默认的8080端口(否则https://127.0.0.1:443/cas/login可以访问到的同时,http://127.0.0.1:8080/cas/login也可以访问到)
修改\webapps\cas\WEB-INF\classes目录下的application.properties文件
#设置为true
#false忽略https安全协议使用HTTP协议;true使用https安全协议;
cas.tgc.secure=true
测试访问(不需要配置hosts文件)
省略443端口,访问https://loaclhost/cas
点击继续前往,可以正常访问
通过浏览器可以查看自己本地生成证书时设置的信息
自己做的SSL证书也就是自签名SSL证书,而CA证书就是由正规的CA机构颁发的,两者大不相同。自签名SSL证书是免费的不安全的,不受任何浏览器信任的;
配置hosts文件后重启tomcat也是可以正常访问的(域名最好和自己的证书别名对应起来)
访问https://skl.com/cas/login、https://wzy1/cas/login都可以。
4.HTTPS方式回退到HTTP方式
修改tomcat的server.xml,放开http-8080,注释https-443。
不需要变动\webapps\cas\WEB-INF\classes目录下的application.properties文件中的配置,测试发现即便设置为true,http方式依然可以访问到:
#false忽略https安全协议使用HTTP协议;true使用https安全协议;
cas.tgc.secure=true
5.配置cas数据源——用户信息从Mysql取
准备数据库和用户表
CREATE DATABASE IF NOT EXISTS `db_sso`;
DEFAULT CHARACTER SET utf8;
USE `db_sso`;
DROP TABLE IF EXISTS `t_cas`;
CREATE TABLE `t_cas` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) DEFAULT NULL,
`password` varchar(100) DEFAULT NULL,
`expired` BIGINT DEFAULT 0 COMMENT '是否过期,1为过期,需修改密码',
`disabled` BIGINT DEFAULT 0 COMMENT '是否禁用,1为禁用',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
insert into `t_cas`(`id`,`username`,`password`) values (1,'system','123456');
select @@autocommit;
show variables like '%timeout%';
密码先明文存储
下载依赖包导入到lib目录
去https://mvnrepository.com/下载下列jar包,
添加到E:\2kc-projectSets\1AllCompany\01Gener\gener010-CAS\apache-tomcat-9.0.34-windows-x64\apache-tomcat-9.0.34\webapps\cas\WEB-INF\lib中。
修改application.properties文件
注释掉写死的用户名和密码配置,加上jdbc数据源配置,连接准备好的db_sso数据库查询t_cas表
# 可以修改登录用户名密码,默认casuser::Mellon
# 注释掉写死的认证用户
#cas.authn.accept.users=casuser::Mellon
# 加上jdbc数据源配置
cas.authn.jdbc.query[0].url=jdbc:mysql://localhost:3306/db_sso?autoReconnect=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8
cas.authn.jdbc.query[0].user=root
cas.authn.jdbc.query[0].password=root
cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver
cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect
#数据库事务自动提交,默认true自动提交
cas.authn.jdbc.query[0].autocommit=true
#查询结果必须包含密码字段
cas.authn.jdbc.query[0].sql=select * from t_cas where username=?
#用户表密码字段(必须)
cas.authn.jdbc.query[0].fieldPassword=password
#指定是否过期字段,1为过期,需要修改密码
cas.authn.jdbc.query[0].fieldExpired=expired
#指定是否禁用字段,1为禁用
cas.authn.jdbc.query[0].fieldDisabled=disabled
启动测试
以用户表的system - 123456登录,登录成功
expired字段设置为1,过期
disabled字段设置为1,禁用
配置密码加密校验
修改t_cas表密码为密文
SELECT SHA(123456);#7c4a8d09ca3762af61e59520943dc26494f8941b
修改application.properties文件,填加以下加密配置:
# 加密策略,默认NONE不加密
#NONE|DEFAULT|STANDARD|BCRYPT|SCRYPT|PBKDF2
cas.authn.jdbc.query[0].passwordEncoder.type=DEFAULT
# 字符类型
cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8
# 加密算法(常用单向加密算法:MD5、SHA、HMAC)
cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=SHA
# 加密盐
#cas.authn.jdbc.query[0].passwordEncoder.secret=
# 加密字符长度
#cas.authn.jdbc.query[0].passwordEncoder.strength=16
启动测试
输入用户名system,密码依然输123456,依然可以成功登录,加密配置成功
三、CAS5.3服务端搭建——导入idea(不放tomcat)
1.环境准备
在cas-overlay-template-5.3.zip解压缩后的文件夹中打开cmd,将文件夹中的build.cmd文件拖入cmd窗口,然后空格+run,回车[也可以用mvn clean package命令,都可以在target下生成war包,不同的是前者还可以启动项目后者只能打包],就会编译了,编译过程可能报错,无须理会
编译完成会生成target文件夹,target文件夹下会生成cas.war
导入项目到idea
导入后项目的初始结构
导入后Project structure中各配置项默认效果,无须改动
修改jdk版本:File->Settings
创建src-main-java和src-main-resources两个文件夹
使target文件夹也显示在项目结构中
将target/cas/WEB-INF/classes下servies文件夹和application.properties文件和log4j2.xml复制到resources文件夹下
==》
2.HTTP方式
由于我这里不用证书(不使用https),修改application.properties,将这三行注释掉
不注释会报错java.io.FileNotFoundException: \etc\cas\thekeystore (系统找不到指定的文件。)
继续修改application.properties,追加配置
#false,忽略https安全协议使用HTTP协议
cas.tgc.secure=false
#是否开启json识别功能,默认为false
cas.serviceRegistry.initFromJson=true
#加载json资源-第一次使用此配置-暂不清楚具体作用
cas.serviceRegistry.json.location=classpath:/services
#自动扫描服务配置,默认开启
#cas.serviceRegistry.watcherEnabled=true
#120秒扫描一遍
#cas.serviceRegistry.repeatInterval=120000
#延迟15秒开启
#cas.serviceRegistry.startDelay=15000
添加支持http请求
在idea的Terminal面板执行build.cmd run重新编译,访问:http://localhost:8443/cas,注意是8443,且cas不能省略,,输入默认的用户名/密码:casuser/Mellon,登录成功
注意不要用build.cmd bootrun(好像是gradle中的命令)启动,否则会报错。
输入http://wzy2:8443/cas也可以访问,可见hosts配置文件既适用http,也适用https。
3.HTTP方式——配置cas数据源——用户信息从Mysql取(有些步骤之前已完成)
准备数据库和用户表
CREATE DATABASE IF NOT EXISTS `db_sso`;
DEFAULT CHARACTER SET utf8;
USE `db_sso`;
DROP TABLE IF EXISTS `t_cas`;
CREATE TABLE `t_cas` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) DEFAULT NULL,
`password` varchar(100) DEFAULT NULL,
`expired` BIGINT DEFAULT 0 COMMENT '是否过期,1为过期,需修改密码',
`disabled` BIGINT DEFAULT 0 COMMENT '是否禁用,1为禁用',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
insert into `t_cas`(`id`,`username`,`password`) values (1,'system','123456');
select @@autocommit;
show variables like '%timeout%';
密码先明文存储
添加pom依赖
添加完Reimport一下(pom文件中有的自带配置会报红暂不用理会)
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-jdbc</artifactId>
<version>5.3.2</version>
</dependency>
<!--这个包不用单独引入,上面的包已经包含了这个包-->
<!--<dependency>-->
<!--<groupId>org.apereo.cas</groupId>-->
<!--<artifactId>cas-server-support-jdbc-authentication</artifactId>-->
<!--<version>5.3.2</version>-->
<!--</dependency>-->
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-jdbc-drivers</artifactId>
<version>5.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency>
注意添加到的位置
补充:不停止build.cmd run的执行,去maven clean时会报错
修改application.properties文件
注释掉写死的用户名和密码配置,加上jdbc数据源配置,连接准备好的db_sso数据库查询t_cas表
# 可以修改登录用户名密码,默认casuser::Mellon
# 注释掉写死的认证用户
#cas.authn.accept.users=casuser::Mellon
# 加上jdbc数据源配置
cas.authn.jdbc.query[0].url=jdbc:mysql://localhost:3306/db_sso?autoReconnect=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8
cas.authn.jdbc.query[0].user=root
cas.authn.jdbc.query[0].password=root
cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver
cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect
#数据库事务自动提交,默认true自动提交
cas.authn.jdbc.query[0].autocommit=true
#查询结果必须包含密码字段
cas.authn.jdbc.query[0].sql=select * from t_cas where username=?
#用户表密码字段(必须)
cas.authn.jdbc.query[0].fieldPassword=password
#指定是否过期字段,1为过期,需要修改密码
cas.authn.jdbc.query[0].fieldExpired=expired
#指定是否禁用字段,1为禁用
cas.authn.jdbc.query[0].fieldDisabled=disabled
build.cmd run启动测试
以用户表的system - 123456登录,登录成功
expired字段设置为1,过期
disabled字段设置为1,禁用
配置密码加密校验
修改t_cas表密码为密文
SELECT SHA(123456);#7c4a8d09ca3762af61e59520943dc26494f8941b
修改application.properties文件,填加以下加密配置:
# 加密策略,默认NONE不加密
#NONE|DEFAULT|STANDARD|BCRYPT|SCRYPT|PBKDF2
cas.authn.jdbc.query[0].passwordEncoder.type=DEFAULT
# 字符类型
cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8
# 加密算法(常用单向加密算法:MD5、SHA、HMAC)
cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=SHA
# 加密盐
#cas.authn.jdbc.query[0].passwordEncoder.secret=
# 加密字符长度
#cas.authn.jdbc.query[0].passwordEncoder.strength=16
build.cmd run启动测试
输入用户名system,密码依然输123456,依然可以成功登录,加密配置成功
4.HTTPS方式——搭建本地HTTPS服务(有些步骤之前已完成)
[之前讲放tomcat且采用HTTPS方式时已经配置完成]-生成秘钥库和证书并把证书导入jdk证书库(不过之前生成证书的参数设置有误导致在第五步客户端访问服务端时出现问题(这里没有影响),正确的步骤请看第五步!)
在第五步客户端访问服务端时出现的问题第五步不再作记录,这里记录一下出现的问题:
客户端:
页面:
修改application.properties,cas.tgc.secure设为true
修改application.properties,放开注释并修改值(不修改FileNotFoundException:)
修改为
#上面生成的秘钥库保存位置
server.ssl.key-store=file:E:/2kc-projectSets/1AllCompany/01Gener/gener010-CAS/secretkey
#上面输入保存的口令
server.ssl.key-store-password=123456
#上面输入保存的口令
server.ssl.key-password=123456
[之前讲解HTTP方式时已经配置完成]-配置数据源和密码加密
(略)
测试访问,OK
访问http://localhost:8443/cas,提示Bad Request
访问https://localhost:8443/cas,正常且system/123456登录成功
[配置失败!--忽略这一步]——IDEA中配置独立tomcat代替build.cmd run启动
在IDEA开发阶段仍采用build.cmd run启动——发布时打成war包放到tomcat(tomcat可在linux后台启动)的webapps文件夹即可。
打成war包命令:mvn clean package 或 build.cmd run
四、服务端添加自定义代码(导入idea、https方式)
1.自定义加密算法
新建加密工具类
package com.kaytune.cas.encode;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.password.PasswordEncoder;
import sun.misc.BASE64Encoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
/**
* @beLongProjecet: cas-overlay
* @beLongPackage: com.kaytune.cas.encode
* @author: sizzled
* @createTime: 2022/12/02 15:10
* @description: 自定义加密工具类
* @version: v1.0
*/
public class MyPasswordEncoder implements PasswordEncoder {
private final Logger log = LoggerFactory.getLogger(MyPasswordEncoder.class);
//盐
private static String salt = "hqw";
@Override/*encode方法用于自定义加密逻辑,在matches方法中调用*/
public String encode(CharSequence charSequence) {
// charSequence为用户输入的用户密码
String encodeStr = charSequence.toString();
String newPW = encodeStr + salt;
MessageDigest md5 = null;
String result = "";
try {
md5 = MessageDigest.getInstance("MD5");//NoSuchAlgorithmException
BASE64Encoder base64Encoder = new BASE64Encoder();
result = base64Encoder.encode(md5.digest(newPW.getBytes(StandardCharsets.UTF_8))).toLowerCase();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
@Override
public boolean matches(CharSequence charSequence, String str) {
// charSequence用户输入的密码,str字符串为数据库中密码字段值
// 判断密码为空,直接返回false
if (StringUtils.isBlank(charSequence)) {
return false;
}
//【调用上面的encode对请求密码进行MD5处理】
String pass = this.encode(charSequence);
/*请求密码为:123456 ,数据库密码为:0svsnofwzoqpkskisgtsfa==,加密后的请求密码为:0svsnofwzoqpkskisgtsfa==*/
log.info("请求密码为:{} ,数据库密码为:{},加密后的请求密码为:{}", charSequence, str, pass);
//比较密码是否相等
return pass.equals(str);
}
}
修改数据库明文密码123456为经上面加密算法加密后的密文
修改application.properties配置
修改log4j2.xml配置打印自己代码中日志
由于上面的加密工具类使用了
private final Logger log = LoggerFactory.getLogger(MyPasswordEncoder.class);
log.info("请求密码为:{} ,数据库密码为:{},加密后的请求密码为:{}", charSequence, str, pass);
所以需要添加下面三个配置到log4j2.xml的指定位置,注意最后一个配置的name
<!--自定义日志-->
<RollingFile name="myLog" fileName="${baseDir}/myLog.log" append="true"
filePattern="${baseDir}/myLog-%d{yyyy-MM-dd-HH}-%i.log">
<PatternLayout pattern="%highlight{%d %p [%c] - <%m>}%n"/>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="10 MB"/>
<TimeBasedTriggeringPolicy />
</Policies>
<DefaultRolloverStrategy max="5" compressionLevel="9">
<Delete basePath="${baseDir}" maxDepth="2">
<IfFileName glob="*/*.log.gz" />
<IfLastModified age="7d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<!--自定义日志-->
<CasAppender name="casMyLog">
<AppenderRef ref="myLog" />
</CasAppender>
<!--自定义日志-->
<AsyncLogger name="com.kaytune.cas.encode" level="info" additivity="false" includeLocation="true">
<AppenderRef ref="casMyLog"/><!--打印到文件-->
<AppenderRef ref="casConsole"/><!--打印到控制台-->
</AsyncLogger>
测试
build.cmd run脚本启动程序,system/123456登录成功,system/123456789登录失败。
2.其它
(自定义登录验证、白名单黑名单等)
五、创建客户端并测试SSO
1.生成秘钥库和证书并把证书导入jdk证书库(上面配置有误,这里是正确配置)
定义好认证中心域名,下面配置需要保持一致(正是之前生成证书时存在的问题)
自定义为:casserver.com
生成秘钥库
cmd执行
keytool -genkey -alias casserver -keyalg RSA -keystore E:/2kc-projectSets/1AllCompany/01Gener/gener010-CAS/casserver.keystore #-alias指定密钥库别名为casserver #-keyalg指定加密算法 #末尾的casserver.keystore是将要生成的密钥库文件 -alias 产生别名 -keystore 指定密钥库的名称(产生的各类信息将不在.keystore文件中) -keyalg 指定密钥的算法 (如 RSA DSA(如果不指定默认采用DSA)) -validity 指定创建的证书有效期多少天 -keysize 指定密钥长度 -storepass 指定密钥库的密码(获取keystore信息所需的密码) -keypass 指定别名条目的密码(私钥的密码) -dname 指定证书拥有者信息 例如: "CN=名字与姓氏,OU=组织单位名称,O=组织名称,L=城市或区域名称,ST=州或省份名称,C=单位的两字母国家代码" -list 显示密钥库中的证书信息 -v 显示密钥库中的证书详细信息 -export 将别名指定的证书导出到文件 -file 参数指定导出到文件的文件名 -delete 删除密钥库中某条目 -printcert 查看导出的证书信息 -keypasswd 修改密钥库中指定条目口令 -storepasswd 修改keystore口令 -import 将已签名数字证书导入密钥库
在E:\2kc-projectSets\1AllCompany\01Gener\gener010-CAS下生成casserver.keystore秘钥库:
基于秘钥库导出证书
cmd执行
keytool -export -trustcacerts -alias casserver -file E:/2kc-projectSets/1AllCompany/01Gener/gener010-CAS/casserver.cer -keystore E:/2kc-projectSets/1AllCompany/01Gener/gener010-CAS/casserver.keystore #前面的路径是要导出证书的位置和证书名称 #后面的路径是之前密钥库的路径,别名和秘钥库别名casserver保持一致
在E:\2kc-projectSets\1AllCompany\01Gener\gener010-CAS下生成了casserver.cer证书:
把证书导入到JDK证书库
cmd执行
keytool -import -trustcacerts -alias casserver -file E:/2kc-projectSets/1AllCompany/01Gener/gener010-CAS/casserver.cer -keystore "E:/1kc-devtools/jdk/jre/lib/security/cacerts" #别名和前面的别名casserver保持一致即可 #前面路径是前面生成的证书的位置,后面是个人jdk中cacerts的所在目录
补充:若证书别名casserver已存在会不能重复添加,如何删除jdk证书库的旧证书?
keytool -delete -alias casserver -keystore E:/1kc-devtools/jdk/jre/lib/security/cacerts #casserver是已存在证书的别名,E:/1kc-devtools/jdk/jre/lib/security/cacerts是个人jdk的cacerts路径 #输入口令:changeit,回车,ok。
2.更新服务端的application.properties和hosts文件
注意:hosts文件不支持配置端口号。
3.创建一个空的Spring Boot项目并引入依赖
<!--构建cas客户端 start-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--<dependency>cas-client-autoconfig-support中包含的有
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.6.1</version>
</dependency>-->
<dependency>
<groupId>net.unicon.cas</groupId>
<artifactId>cas-client-autoconfig-support</artifactId><!--是核心功能,包含认证和校验的过滤器-->
<version>2.3.0-GA</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.6.7</version>
</dependency>
<!--构建cas客户端 end-->
4.启动类添加注解
@EnableCasClient
5.添加首页Controller
package com.kaytune.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
* @beLongProjecet: cas-client
* @beLongPackage: com.kaytune.controller
* @author: sizzled
* @createTime: 2022/12/04 21:11
* @description:
* @version: v1.0
*/
@Controller
public class IndexController {
@RequestMapping("/index")
public ModelAndView index(){
ModelAndView model = new ModelAndView();
model.setViewName("index");
return model;
}
}
6.添加首页模板
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>cas_client</title>
</head>
<body>
欢迎:[<h3 th:text="${session._const_cas_assertion_.principal.name}"></h3>]</br>
cas_client
</body>
</html>
${session._const_cas_assertion_.principal.name} 登录用户名
7.勾选Allow parallel run,启动3个实例
一个服务多个端口运行(Allow parallel run) - 周文豪 - 博客园
yml中每个实例配置
否则报错:
# 实例1
cas:
server-url-prefix: https://casserver.com:8443/cas
server-login-url: https://casserver.com:8443/cas/login
client-host-url: http://localhost:8881
validation-type: cas3
server:
port: 8881
## 实例2
#cas:
# server-url-prefix: https://casserver.com:8443/cas
# server-login-url: https://casserver.com:8443/cas/login
# client-host-url: http://localhost:8882/
# validation-type: cas3
#server:
# port: 8882
## 实例3
#cas:
# server-url-prefix: https://casserver.com:8443/cas
# server-login-url: https://casserver.com:8443/cas/login
# client-host-url: http://localhost:8883/
# validation-type: cas3
#server:
# port: 8883
8. 单点登录测试
启动服务端和三个客户端
访问客户端1:http://localhost:8881/index
跳转登录界面,输入system/123456
点击登录按钮,登录成功
访问客户端2:http://localhost:8882/index,不用登录
访问客户端3:http://localhost:8883/index,不用登录
访问服务端:https://casserver.com:8443/cas,不用登录,点击登出再次访问客户端需要重新登录
9.单点登出
创建登出控制器
注销本地会话,重定向到服务端的/cas/logout接口统一登出
package com.kaytune.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @beLongProjecet: cas-client
* @beLongPackage: com.kaytune.controller
* @author: sizzled
* @createTime: 2022/12/06 14:33
* @description: 登出
* @version: v1.0
*/
@Controller
public class LogoutController {
@RequestMapping("logout")
public String logout(HttpSession httpSession){
//注销本地会话
httpSession.invalidate();
//重定向
return "redirect:https://casserver.com:8443/cas/logout";
}
}
页面添加登出按钮
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>cas_client</title>
</head>
<body>
欢迎:[<h3 th:text="${session._const_cas_assertion_.principal.name}"></h3>]</br>
cas_client
<hr><a href="/logout">统一退出登录</a>
</body>
</html>
测试
启动服务端和三个客户端,分别访问三个客户端http://localhost:8881、http://localhost:8882、http://localhost:8883
在http://localhost:8881页面点击退出
刷新http://localhost:8882、http://localhost:8883页面需要重新登录,测试成功
六、服务端界面修改
1.favicon.ico的修改
放Tomcat时
E:\2kc-projectSets\1AllCompany\01Gener\gener010-CAS\apache-tomcat-9.0.34-windows-x64\apache-tomcat-9.0.34\webapps\cas\WEB-INF\classes\static下:备份默认的放入新的
导入Idea时
新建static文件夹,放入favicon.ico,退出脚本运行,执行mvn clean重新编译,脚本启动
2.登录页面的修改
默认页面
放Tomcat时
11_CAS Server界面修改_哔哩哔哩_bilibili
在E:\2kc-projectSets\1AllCompany\01Gener\gener010-CAS\apache-tomcat-9.0.34-windows-x64\apache-tomcat-9.0.34\webapps\cas\WEB-INF\classes\templates下修改,为了便于修改,在idea中打开E:\2kc-projectSets\1AllCompany\01Gener\gener010-CAS\apache-tomcat-9.0.34-windows-x64\apache-tomcat-9.0.34\webapps\cas\WEB-INF\classes
修改templates\layout.html:使登录页面和登出成功页面去掉默认的头部和尾部
修改templates\casLoginView.html:使登录页面去掉右侧的内容
修改templates\fragments\loginsidebar.html:更改表单下登出按钮所在的提示信息
可以直接注释上面的自己添加下面的代码,也可以不添加下面的代码在classes\messages_zh_CN.properties中修改screen.welcome.security的属性值
#screen.welcome.security=\u51FA\u4E8E\u5B89\u5168\u8003\u8651\uFF0C\u4E00\u65E6\u60A8\u8BBF\u95EE\u8FC7\u90A3\u4E9B\u9700\u8981\u60A8\u63D0\u4F9B\u51ED\u8BC1\u4FE1\u606F\u7684\u5E94\u7528\u65F6\uFF0C\u8BF7\u64CD\u4F5C\u5B8C\u6210\u4E4B\u540E<a href="logout">\u767B\u51FA</a>\u5E76\u5173\u95ED\u6D4F\u89C8\u5668\u3002 screen.welcome.security=\u51fa\u4e8e\u5b89\u5168\u8003\u8651\uff0c\u005b\u52a0\u4e0a\u4e00\u6bb5\u5c41\u8bdd\u005d\uff0c\u4e00\u65e6\u60a8\u8bbf\u95ee\u8fc7\u90a3\u4e9b\u9700\u8981\u60a8\u63d0\u4f9b\u51ed\u8bc1\u4fe1\u606f\u7684\u5e94\u7528\u65f6\uff0c\u8bf7\u64cd\u4f5c\u5b8c\u6210\u4e4b\u540e\u003c\u0061\u0020\u0068\u0072\u0065\u0066\u003d\u0022\u006c\u006f\u0067\u006f\u0075\u0074\u0022\u003e\u767b\u51fa\u003c\u002f\u0061\u003e\u5e76\u5173\u95ed\u6d4f\u89c8\u5668\u3002screen.welcome.instructions=\u8bf7\u8f93\u5165\u60a8\u7684\u7528\u6237\u540d\u548c\u5bc6\u7801.
把上面默认的属性值unicode编码转为中文,修改成想要的中文,再把中文转为unicode编码
在登录页表单的右边设置图片
往static\images中放入一张图片,在static\css\cas.css中添加
#notices .cs { height: 600px; width: 540px; background-image: url("../images/美罗大厦.jpg"); }
在templates\casLoginView.html中添加
导入Idea时
把上面演示的放Tomcat时登录页面的修改,在idea中打开的E:\2kc-projectSets\1AllCompany\01Gener\gener010-CAS\apache-tomcat-9.0.34-windows-x64\apache-tomcat-9.0.34\webapps\cas\WEB-INF\classes文件夹下的已经改好的相关文件夹粘贴到导入Idea方式的工程即可
启动查看效果
七、重要补充
- cas服务端的build目录没啥用不用提交到代码库中,这个文件夹就算删了每次运行都会自动重新生成。
- 自定义的log4j2.xml文件就放在resources目录下,移动并覆盖etc目录下的同名文件的话会导致自定义的日志配置无效。
- 测试发现etc目录可以删除对功能无影响;测试发现maven目录也可以删除对功能无影响。测试发现overlays目录也可以删除对功能无影响。最后的目录结构是这样功能也正常:
- 下面两个pom默认自带的地方可以注释掉。
- 要想在cas服务端新建controller和拦截器并使之生效。需要一些配置,第一步复制overlays\org.apereo.cas.cas-server-webapp-tomcat-5.3.16\WEB-INF\classes\META-INF\spring.factories中的META-INF目录到resources目录下,在spring.factories中追加:第二步新建SpringConfig.java配置类用于扫描包文件注册到spring容器:
- 在cas5.3服务端配置拦截器:尽量采用implements WebMvcConfigurer方式,采用/*extends WebMvcConfigurationSupport*/方式容易导致静态资源被拦截且在配置静态资源不拦截时容易出错。
- cas5.3的源码已经引入了springboot不需要再引入,不需要再被含boot依赖的父模块管理了。
-
/*多属性返回,大坑:返回的时候,json里一定要跟自定义认证策略里的map值一致*/ ,"attributeReleasePolicy" : { /*全部返回*/ "@class": "org.apereo.cas.services.ReturnAllAttributeReleasePolicy", /*只返回指定属性*/ /*"@class" : "org.apereo.cas.services.ReturnAllowedAttributeReleasePolicy", "allowedAttributes" : [ "java.util.ArrayList", [ "username", "password" ] ]*/ }
————————————————
版权声明:本文为CSDN博主「张童瑶」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u014641168/article/details/120906539 - 在resources/services目录下的.json文件中,logoutType:分为FRONT_CHANNEL,BACK_CHANNEL,其中FRONT_CHANNEL:显式登出.cas直接发送http post请求到已认证服务; BACK_CHANNEL:隐式登出.cas发送异步ajax get请求到已认证服务。
八、Debug
九、参考文章
CAS单点登录_Please Sit Down的博客-CSDN博客_cas单点登录CAS单点登录(三)——多种认证方式 - wjj1013 - 博客园
搭建CAS服务(导入IDEA)_KGF886的博客-CSDN博客
自定义登录验证:
CAS+Springboot单点登录 - 腾讯云开发者社区-腾讯云