在实现单点登陆的过程中,我踩了很多坑,浏览了许多资料,终于将CAS的服务端搭建完成了,以下是我这两天搭建的心得,以及引用的一些大佬的资料,希望对大家有帮助。
一,下载源码
首先是下载cas源码,git地址是:https://github.com/apereo/cas-overlay-template (此处注意,一定要选择5.3版本的源码。超过 5.3版本的cas取消了pom,导致很难进行打包,我的项目是使用MAVEN的springboot项目。而5.2版本的源码,在我这部署上去,访问登陆地址时,一直会报404的错误。因此使用5.3版本的。)
二,配置https,并部署到tomcat运行
一路下载完成后,由于cas要求要用https来进行访问,因此,我们首先要来生成一个https证书,并信任他,然后我们需要将cas源码打包成cas.war,放入到tomcat中进行运行验证。此处请参考大神
这个名字想了很久的文章 https://blog.csdn.net/qq_34021712/article/details/80871015 这篇文章只要看到将cas部署到tomcat,并且运行tomcat后能够进入登陆页面即可,overlay那块可以不看。(此处强力此大神的文章,他写的有关shiro的博客非常之详尽,基本上把shiro的所有知识点都整理好了。)
三,将cas源码部署到idea中
在以上步骤完成后,我们已经有一个初步的cas服务端了,但是此时的cas只有默认的账号密码,而我们项目需要用的是应该是让他连接到我们的数据库中进行使用,我这里使用的是mysql数据库。因此需要进行以下操作。
首先,我们将cas源码导入成MAVEN项目到idea中,导入后,在pom中加入以下jar包:
<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>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
然后,我们自己创建一个java源文件,用于之后编写自定义加密的java代码,然后将必要的文件如application.properties、META-INF和log4j2.xml从之前在tomcat跑的cas.war包里面拷贝出来,然后再idea里面配置tomcat,运行结果和之前在外部tomcat的结果一致即表示搭建成功啦。这个部分的具体操作详见文章https://blog.csdn.net/csolo/article/details/95597820 他里面对于这个项目目录的搭建讲得非常详细。
四,将cas项目连接mysql,并实现自定义加密
搭建完项目框架后,重点来啦,就是如何将mysql连接进去(最后我会贴上我的application.properties的内容)。我们只需要打开application.properties,对其进行配置即可。首先配置ssl,这个是用来对https进行处理的,
#你的tomcat.keystore的路径
server.ssl.key-store=file:F:/tomcat.keystore
#你之前在配置https时配置的密码
server.ssl.key-store-password=asdasd
#同上
server.ssl.key-password=asdasd
然后,我们将默认的密码注销掉
#cas.authn.accept.users=casuser::Mellon
最后,我们配置关于mysql的配置
#Query Database Authentication 数据库查询校验用户名开始
#查询账号密码sql,必须包含密码字段
cas.authn.jdbc.query[0].sql=select password from sys_user where username=?
#指定上面的sql查询字段名(必须)
cas.authn.jdbc.query[0].fieldPassword=password
#指定过期字段,1为过期,若过期不可用(可选)
#cas.authn.jdbc.query[0].fieldExpired=expired
#为不可用字段段,1为不可用,需要修改密码(可选)
#cas.authn.jdbc.query[0].fieldDisabled=disabled
#数据库方言hibernate的
#cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect
#数据库驱动
cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver
#数据库连接
cas.authn.jdbc.query[0].url=jdbc:mysql://192.168.4.15:3306/test01?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false
#数据库用户名
cas.authn.jdbc.query[0].user=root
#数据库密码
cas.authn.jdbc.query[0].password=123456
#默认加密策略,通过encodingAlgorithm来指定算法,默认NONE不加密
cas.authn.jdbc.query[0].passwordEncoder.type=com.ucas.CustomPasswordEncoder
cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8
cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=MD5
#Query Database Authentication 数据库查询校验用户名结束
其中,cas.authn.jdbc.query[0].fieldPassword是查询数据库后的密码,cas.authn.jdbc.query[0].sql查询时必须包括这个密码的字段。cas.authn.jdbc.query[0].passwordEncoder.type是用来指定要采用哪种加密方式,NONE表示不加密,Default表示默认,而我们要的自定义加密方式就在此处啦,根据你之前配好的java源目录下的路径,创建一个自定义的加密类,把他的路径拿过来,配置到此处,表示自定义加密,我的路径对应如图:
cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm表示使用哪个加密算法,我这里使用MD5加密。
最后我们只需要实现CustomPasswordEncoder这个自定义类的方法就可以实现自定义加密了。
首先,这个类必须实现PasswordEncoder的接口,重写里面的两个方法,encode()表示你对密码进行加密,加密后的结果;matches()表示你输入的密码经过加密后和数据库的密码进行比对(数据库密码是已经加密完成的密文)。
我的加密算法是MD5加盐加密循环3次,所以,这里推荐使用shiro封装的一个类SimpleHash(如果你要使用这种方式,请到pom导入shiro的jar包,这个就不贴了),这个类直接就可以进行MD5多次加密,非常方便。此次贴上我的自定义加密类的代码。
public class CustomPasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence password) {
try {
//给数据进行md5加密,第一个参数是算法,第二个参数是密码,第三个参数是盐,第四个参数是要
//循环加密几次
SimpleHash hash = new SimpleHash("MD5", "admin", "awdwa", 3);
return hash.toString();
} catch (Exception e) {
return null;
}
}
@Override
public boolean matches(CharSequence charSequence, String encodePassword) {
// 判断密码是否存在
if (charSequence == null) {
return false;
}
//通过md5加密后的密码
String pass = this.encode(charSequence.toString());
//比较密码是否相等的问题
return pass.equals(encodePassword);
}
}
走到这一步,我们的cas服务端就搭建完毕啦,最后贴上我的application.properties的内容:
##
# CAS Server Context Configuration
#
server.context-path=/cas
server.port=8443
#你的tomcat.keystore的路径
server.ssl.key-store=file:F:/tomcat.keystore
#你之前在配置https时配置的密码
server.ssl.key-store-password=asdasd
#同上
server.ssl.key-password=asdasd
server.max-http-header-size=2097152
server.use-forward-headers=true
server.connection-timeout=20000
server.error.include-stacktrace=ALWAYS
server.compression.enabled=true
server.compression.mime-types=application/javascript,application/json,application/xml,text/html,text/xml,text/plain
server.tomcat.max-http-post-size=2097152
server.tomcat.basedir=build/tomcat
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%t %a "%r" %s (%D ms)
server.tomcat.accesslog.suffix=.log
server.tomcat.min-spare-threads=10
server.tomcat.max-threads=200
server.tomcat.port-header=X-Forwarded-Port
server.tomcat.protocol-header=X-Forwarded-Proto
server.tomcat.protocol-header-https-value=https
server.tomcat.remote-ip-header=X-FORWARDED-FOR
server.tomcat.uri-encoding=UTF-8
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
##
# CAS Cloud Bus Configuration
#
spring.cloud.bus.enabled=false
# Indicates that systemPropertiesOverride can be used.
# Set to false to prevent users from changing the default accidentally. Default true.
spring.cloud.config.allow-override=true
# External properties should override system properties.
spring.cloud.config.override-system-properties=false
# When allowOverride is true, external properties should take lowest priority, and not override any
# existing property sources (including local config files).
spring.cloud.config.override-none=false
# spring.cloud.bus.refresh.enabled=true
# spring.cloud.bus.env.enabled=true
# spring.cloud.bus.destination=CasCloudBus
# spring.cloud.bus.ack.enabled=true
endpoints.enabled=false
endpoints.sensitive=true
endpoints.restart.enabled=false
endpoints.shutdown.enabled=false
# Control the security of the management/actuator endpoints
# The 'enabled' flag below here controls the rendering of details for the health endpoint amongst other things.
management.security.enabled=true
management.security.roles=ACTUATOR,ADMIN
management.security.sessions=if_required
management.context-path=/status
management.add-application-context-header=false
# Define a CAS-specific "WARN" status code and its order
management.health.status.order=WARN, DOWN, OUT_OF_SERVICE, UNKNOWN, UP
# Control the security of the management/actuator endpoints
# With basic authentication, assuming Spring Security and/or relevant modules are on the classpath.
security.basic.authorize-mode=role
security.basic.path=/cas/status/**
# security.basic.enabled=true
# security.user.name=casuser
# security.user.password=
##
# CAS Web Application Session Configuration
#
server.session.timeout=300
server.session.cookie.http-only=true
server.session.tracking-modes=COOKIE
##
# CAS Thymeleaf View Configuration
#
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.cache=true
spring.thymeleaf.mode=HTML
spring.thymeleaf.template-resolver-order=100
##
# CAS Log4j Configuration
#
# logging.config=file:/etc/cas/log4j2.xml
server.context-parameters.isLog4jAutoInitializationDisabled=true
##
# CAS AspectJ Configuration
#
spring.aop.auto=true
spring.aop.proxy-target-class=true
##
# CAS Authentication Credentials
#
#cas.authn.accept.users=casuser::Mellon
#Query Database Authentication 数据库查询校验用户名开始
#查询账号密码sql,必须包含密码字段
cas.authn.jdbc.query[0].sql=select password from sys_user where username=?
#指定上面的sql查询字段名(必须)
cas.authn.jdbc.query[0].fieldPassword=password
#指定过期字段,1为过期,若过期不可用(可选)
#cas.authn.jdbc.query[0].fieldExpired=expired
#为不可用字段段,1为不可用,需要修改密码(可选)
#cas.authn.jdbc.query[0].fieldDisabled=disabled
#数据库方言hibernate的
#cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect
#数据库驱动
cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver
#数据库连接
cas.authn.jdbc.query[0].url=jdbc:mysql://192.168.4.15:3306/test01?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false
#数据库用户名
cas.authn.jdbc.query[0].user=root
#数据库密码
cas.authn.jdbc.query[0].password=123456
#默认加密策略,通过encodingAlgorithm来指定算法,默认NONE不加密
cas.authn.jdbc.query[0].passwordEncoder.type=com.ucas.CustomPasswordEncoder
cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8
cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=MD5
#Query Database Authentication 数据库查询校验用户名结束