跳至主要內容

搭建Cas单点认证

知识库运维技巧开发搭建CAS大约 4 分钟

CAS 全称为 Central Authentication Service 即中央认证服务,是一个企业多语言单点登录的解决方案,并努力去成为一个身份验证和授权需求的综合平台。

CAS 是由 Yale 大学发起的一个企业级的、开源的项目,旨在为 Web 应用系统提供一种可靠的单点登录解决方法(属于 Web SSO )。

CAS 协议至少涉及三方:客户端 Web 浏览器,请求身份验证的 Web 应用程序和 CAS 服务器。 它也可能涉及后端服务,如数据库服务器,它没有自己的 HTTP 接口,但与 Web 应用程序进行通信。

源码文件

# Github: https://github.com/apereo/cas
# 下载链接: https://github.com/apereo/cas/tag
# 开发文档: https://apereo.github.io/cas/5.2.x/index.html
# 官网: https://www.apereo.org/projects/cas
# WAR的代码架子: https://github.com/apereo/cas-overlay-template
# 修改定制版本: https://gitee.com/haijunit/cas-overlay-template
git clone -b 5.3 https://gitee.com/haijunit/cas-overlay-template.git
#git clone -b 5.3 https://github.com/apereo/cas-overlay-template.git
mvn clean compile package

修改 pom 文件

<!-- 添加认证所需要的依赖 -->
<dependencies>
    <!--新增支持jdbc验证-->
    <dependency>
        <groupId>org.apereo.cas</groupId>
        <artifactId>cas-server-support-jdbc</artifactId>
        <version>${cas.version}</version>
    </dependency>
    <!--数据库驱动依赖-->
    <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-ldap</artifactId>
        <version>${cas.version}</version>
    </dependency>
    <!-- 白名单(Whitelist)认证 -->
    <dependency>
        <groupId>org.apereo.cas</groupId>
        <artifactId>cas-server-support-generic</artifactId>
        <version>${cas.version}</version>
    </dependency>
    <!--
    ...Additional dependencies may be placed here...
    -->
</dependencies>
<repositories>
  <repository>
      <id>shibboleth-releases</id>
      <url>https://build.shibboleth.net/nexus/content/repositories/releases</url>
  </repository>
  <!--添加国内镜像源地址-->
  <repository>
      <id>maven-ali</id>
      <url>http://maven.aliyun.com/nexus/content/groups/public//</url>
      <releases>
          <enabled>true</enabled>
      </releases>
      <snapshots>
          <enabled>true</enabled>
          <updatePolicy>always</updatePolicy>
          <checksumPolicy>fail</checksumPolicy>
      </snapshots>
  </repository>
</repositories>

WAR 打包

# WAR打包
#./build.cmd package
./build.sh package

JDBC 认证

application.properties
##
# Query Database Authentication 数据库查询校验用户名开始
#
#查询账号密码SQL,必须包含密码字段
cas.authn.jdbc.query[0].sql=select * from 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

#数据库dialect配置
cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect
#数据库连接
cas.authn.jdbc.query[0].url=jdbc:mysql://127.0.0.1:3306/cas?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
#数据库用户名
cas.authn.jdbc.query[0].user=root
#数据库用户密码
cas.authn.jdbc.query[0].password=123456

#数据库事务自动提交
cas.authn.jdbc.query[0].autocommit=false
#数据库驱动
cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver
#超时配置
cas.authn.jdbc.query[0].idleTimeout=5000

# https://apereo.github.io/cas/5.3.x/installation/Configuration-Properties-Common.html#password-encoding
#默认加密策略,通过encodingAlgorithm来指定算法,默认NONE不加密
# 可选 NONE|DEFAULT|STANDARD|BCRYPT|SCRYPT|PBKDF2
#cas.authn.jdbc.query[0].passwordEncoder.type=NONE
cas.authn.jdbc.query[0].passwordEncoder.type=DEFAULT
cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8
cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=MD5
# 加密盐
#cas.authn.jdbc.query[0].passwordEncoder.secret=
# 加密字符长度
#cas.authn.jdbc.query[0].passwordEncoder.strength=16
mysql.sql
DROP DATABASE IF EXISTS `cas`;

CREATE DATABASE `cas` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

USE `cas`;

DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE sys_user (
 id int(11) NOT NULL AUTO_INCREMENT,
 username varchar(30) NOT NULL,
 password varchar(64) NOT NULL,
 expired int,   -- 是否过期 1为不可用,0为正常
 disabled int,  -- 是否禁用 1为不可用,0为正常
 locked int,    -- 是否锁定 1为不可用,0为正常
 PRIMARY KEY (id)
);

-- 正常用户
insert into sys_user values ('1','admin','e10adc3949ba59abbe56e057f20f883e',0, 0, 0);
insert into sys_user values ('2','cs01','e10adc3949ba59abbe56e057f20f883e',0, 0, 0);
-- 禁用账户
insert into sys_user values('3','cs02','e10adc3949ba59abbe56e057f20f883e',0, 1, 0);
-- 过期账户
insert into sys_user values('4','cs03','e10adc3949ba59abbe56e057f20f883e',1, 0, 0);
-- 锁定账户
insert into sys_user values('5','cs04','e10adc3949ba59abbe56e057f20f883e',0, 0, 1);

Ldap 认证

application.properties
###################ldap authentication######################
cas.authn.ldap[0].principalAttributeList=sn,cn:commonName,givenName,eduPersonTargettedId:SOME_IDENTIFIER
cas.authn.ldap[0].collectDnAttribute=false
cas.authn.ldap[0].principalDnAttributeName=principalLdapDn
cas.authn.ldap[0].allowMultiplePrincipalAttributeValues=true
cas.authn.ldap[0].allowMissingPrincipalAttributeValue=true
cas.authn.ldap[0].credentialCriteria=

cas.authn.ldap[0].ldapUrl=ldap://127.0.0.1:389
cas.authn.ldap[0].bindDn=cn=admin,dc=txra,dc=com
cas.authn.ldap[0].bindCredential=123456
cas.authn.ldap[0].baseDn=ou=bjtxra,o=txra,dc=txra,dc=com

cas.authn.ldap[0].poolPassivator=NONE
cas.authn.ldap[0].connectionStrategy=
cas.authn.ldap[0].providerClass=org.ldaptive.provider.unboundid.UnboundIDProvider
cas.authn.ldap[0].connectTimeout=PT5S
cas.authn.ldap[0].trustCertificates=
cas.authn.ldap[0].keystore=
cas.authn.ldap[0].keystorePassword=
cas.authn.ldap[0].keystoreType=JKS
cas.authn.ldap[0].minPoolSize=3
cas.authn.ldap[0].maxPoolSize=10
cas.authn.ldap[0].validateOnCheckout=true
cas.authn.ldap[0].validatePeriodically=true
cas.authn.ldap[0].validatePeriod=PT5M
cas.authn.ldap[0].validateTimeout=PT5S
cas.authn.ldap[0].failFast=true
cas.authn.ldap[0].idleTime=PT10M
cas.authn.ldap[0].prunePeriod=PT2H
cas.authn.ldap[0].blockWaitTime=PT3S
cas.authn.ldap[0].useSsl=false
cas.authn.ldap[0].useStartTls=false
cas.authn.ldap[0].responseTimeout=PT5S
cas.authn.ldap[0].allowMultipleDns=false
cas.authn.ldap[0].allowMultipleEntries=false
cas.authn.ldap[0].followReferrals=false
cas.authn.ldap[0].binaryAttributes=objectGUID,someOtherAttribute
cas.authn.ldap[0].name=
cas.authn.ldap[0].type=AUTHENTICATED
cas.authn.ldap[0].searchFilter=(|(uid={user})(mail={user})(mobile={user}))

白名单认证

application.properties
##
# 白名单——file配置
cas.authn.file.separator=::
#cas.authn.file.filename=file:///Users/anumbrella/file
#cas.authn.file.filename=claapath:user.txt
cas.authn.file.name=

##
# 黑名单配置
cas.authn.reject.users=test,anumbrella
cas.authn.reject.name=

##
# 白名单——json配置
#cas.authn.json.location=claapath:user.json
#cas.authn.json.name=


# 密码明文
cas.authn.jdbc.query[0].passwordEncoder.type=NONE
cat >> user.txt <<EOF
admin::admin
test::test
EOF

cat >> user.json <<EOF
{
  "@class" : "java.util.LinkedHashMap",
  "admin" : {
    "@class" : "org.apereo.cas.adaptors.generic.CasUserAccount",
    "password" : "admin",
    "status" : "OK",
    "expirationDate" : "2222-01-01"
  }
}
EOF