CAS 的安装与配置

发送反馈


iServer 、iPortal 及 iEdge 支持基于 CAS 的单点登录。CAS(Central Authentication Service)是 Yale 大学发起的构建 Web SSO 的 Java 开源项目。用户配置单点登录时,需设置 CAS 认证服务器,CAS 认证服务器负责完成对用户信息的认定,可单独部署于网络环境中。配置使用 CAS 单点登录的过程具体请详见配置使用 CAS 单点登录

要使用 CAS 单点登录,首先需要搭建 CAS 服务,这里主要介绍 CAS 3.X 和 CAS 5.X 的配置方法。

配置 CAS 3.X

这里以在 Windows 系统中通过 cas-server-webapp-3.4.war 搭建 CAS 服务,并以 MySQL 作为存储用户信息的数据库为例进行说明。

准备 cas-server-webapp-3.4 包

http://www.apereo.org 下载 CAS 3.4  的安装包,然后将 cas-server-webapp-3.4.war 解压缩,解压缩的文件夹重命名为 cas,在 cas\WEB-INF\lib 中添加以下 jar 包,用于连接用户账户的数据库:

此外,还需要下载 cas-server-3.4-release.zip,然后将此 zip 包里 modules 文件夹中的 jar 包都添加到 cas\WEB-INF\lib 文件夹里(除了 cas-server-core-3.4.jar,因为 cas-server-webapp-3.4 里已经包含)。

配置 CAS 连接的数据源

修改 cas\WEB-INF\deployerConfigContext.xml,在其中添加以下配置:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

    <!--根据用户账号保存的数据库类型决定-->

    <property name="driverClassName" value="com.mysql.jdbc.Driver" />

    <!--用户账号的数据库连接方式-->

    <property name="url" value="jdbc:mysql://localhost:3306/iportalusers" />

    <!--本地MySQL数据库的用户名和密码-->

    <property name="username" value="root" />

    <property name="password" value="root" />

</bean>

注释掉以下这行代码:

<!-- <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" /> -->

在<property name="authenticationHandlers">节点的<list>节点下,添加以下内容:

<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" p:httpClient-ref="httpClient" />

<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">

    <property name="dataSource" ref="dataSource" />

    <property name="sql" value="select password  from users  where lower(user ) = lower(?)" />

</bean>

上述代码中粗体字段的含义如下:

配置 CAS 登录后返回的属性信息

修改  cas\WEB-INF\deployerConfigContext.xml,注释掉以下几行代码:

<!--   <bean id="attributeRepository" class="org.jasig.services.persondir.support.StubPersonAttributeDao">

  <property name="backingMap">

    <map>

      <entry key="uid" value="uid" />

      <entry key="eduPersonAffiliation" value="eduPersonAffiliation" />

      <entry key="groupMembership" value="groupMembership" />

    </map>

  </property>

</bean>  -->

添加以下配置:

<bean class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao" id="attributeRepository">

  <!-- 指定使用的数据源,此处dataSource是已配置好的数据源 -->

  <constructor-arg index="0" ref="dataSource"/>

  <!-- 从数据库中查询信息的SQL语句,users是用户账号的表名 -->

  <constructor-arg index="1" value="select * from users where {0}"/>

  <property name="queryAttributeMapping">

    <map>

    <!-- user 是账户表的名称字段 -->

      <entry key="username" value="user "/>

    </map>

  </property>

  <property name="resultAttributeMapping">

    <map>

    <!—配置返回的字段信息:usertype是账户的类型 ,id是账户的id,roletype用于iPortal配置,即CAS用户属性字段    -->

    <entry key="usertype " value="roletype "/>

    <entry key="id" value="guid"/>

    </map>

  </property>

</bean>

上述代码中粗体字段的含义如下:

找到 class 为 org.jasig.cas.authentication.AuthenticationManagerImpl 的 bean,找到其<property name="credentialsToPrincipalResolvers">节点的<list>节点,修改<list>节点的

<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" />

为:

<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" >

  <property name="attributeRepository" ref="attributeRepository" />

</bean>

返回属性信息还需要修改 CAS 目录下的 WEB-INF\view\jsp\protocol\2.0\casServiceValidationSuccess.jsp 文件,具体方法是在<cas:user>${fn:escapeXml(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.id)}</cas:user>后面添加:

<cas:attributes>

<cas:test>test_value</cas:test>

<c:forEach var="auth" items="${assertion.chainedAuthentications}">

<c:forEach var="attr" items="${auth.principal.attributes}">

<cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}>

</c:forEach>

</c:forEach>

</cas:attributes>

允许以 http 的方式登录 CAS Server

修改 cas\WEB-INF\spring-configuration\ticketGrantingTicketCookieGenerator.xml 文件,使得可以使用 http 协议的方式登录 CAS:将 CookieRetrievingCookieGenerator 的 p:cookieSecure 设置为"false"。

以上配置设置完成后,将 CAS 文件夹放置到 tomcat 的 webapps 目录里,启动 tomcat,此时可以访问 http://casserver:port/cas,用上面配置的 iportalusers 数据库中 users 表的用户账户登录 CAS。

配置 CAS 5.X

iServer/iPortal/iEdge 从 9D 版本开始支持 CAS 5.x 单点登录,但由于 CAS 5.x 相较于 CAS 3.x 有较大的差异,部署方式也不同,且没有官方推出的 5.x 发行版,所以用户需要手动构建 war 包。CAS 的服务端搭建常用的方式有两种:

  1. 基于源码构建

  2. 使用 WAR Overlay 安装

官方推荐使用第二种,配置管理方便,后续升级也容易,因此此处也以 Windows 系统为例介绍使用 WAR Overlay 搭建服务的具体步骤。  

下载 CAS Overlay

由于 CAS 5.X 无发行版本,因此需要使用 Git 下载 CAS Overlay,在切换到下载目录后,输入以下 git 命令进行下载:

git clone -b 5.3 https://github.com/apereo/cas-overlay-template.git

下载完成后,目录下新增了一个名为 cas-overlay-template 的文件夹。

数据库配置

在数据库中创建数据库、表和帐号数据,用于 CAS 进行对 iServer/iPortal/iEdge 账号信息的管理。此处以 MySQL 数据库为例:

CREATE DATABASE `localmysql`;

DROP TABLE IF EXISTS `app_user`;  

CREATE TABLE `app_user` (  

  `id` INT(11) NOT NULL AUTO_INCREMENT,

  `username` VARCHAR(45) DEFAULT NULL,

  `password` VARCHAR(45) DEFAULT NULL,

  `role` VARCHAR(45) DEFAULT NULL,

  PRIMARY KEY (`id`)  

);  

INSERT INTO `app_user` VALUES (1,'cas','1234567','admin');

增加依赖

为实现 iServer (或 iPortal、iEdge) 单点登录的对接,需找到 cas-overlay-template 目录下的 pom.xml 文件,增加依赖。

添加数据库的 JDBC 插件,在 pom.xml 增加如下依赖:

<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>

iServer  (或 iPortal、iEdge) 和 CAS 之间遵循 SAML1.1 协议以实现票证验证响应,因此 CAS 需包含以下依赖来启用对 SAML1.1 的支持:

<dependency>

  <groupId>org.apereo.cas</groupId>

  <artifactId>cas-server-support-saml</artifactId>

  <version>${cas.version}</version>

</dependency>

CAS 以 JSON 格式注册服务,因此需要包含 JSON 依赖包来实现对 JSON 的支持,如下:

 <dependency>

      <groupId>org.apereo.cas</groupId>

      <artifactId>cas-server-support-json-service-registry</artifactId>

      <version>${cas.version}</version>

</dependency>

iServer  (或 iPortal、iEdge) 与 CAS 之间实现票证验证响应时,需要获取代表角色的字段(即前面表里的 role 字段)来验证拥有权限的类型,因此需要增加属性返回依赖包。

<dependency>

      <groupId>org.apereo.cas</groupId>

      <artifactId>cas-server-core-authentication-attributes</artifactId>

      <version>${cas.version}</version>

</dependency>

至此,iServer/iPortal/iEdge 对接 CAS 需用到的依赖已添加完毕。使用如下命令进行打包:

mvn package

打包结束后,把打包生成的 CAS.war 复制到 tomcat 的 webapps 目录中 。

修改配置文件

接下来修改配置文件,但要注意,此时还不能启动 tomcat。

首先打开  cas \WEB-INF\classes\services 目录下的 HTTPSandIMAPS-10000001.json 文件,如下:

由 serviceId 参数可知,当前 CAS 只支持 https 和 imaps 这2个协议,还需增加 http 协议。如下:

增加注册服务的配置,如下:

增加返回所有的相关属性的配置,如下:

保存 HTTPSandIMAPS-10000001.json 文件。至此,完成对配置文件的修改。

配置数据库的连接等参数

在 cas\WEB-INF\classes 目录下新建 application.properties 文件,增加配置项,开启 JSON 注册服务,如下:

#开启json注册服务

cas.serviceRegistry.initFromJson=true

增加配置项,设置服务注册配置文件位置,如下:

#设置服务注册配置文件位置

cas.serviceRegistry.json.location=classpath:/services

增加配置项,增加数据库配置,以用于 CAS 服务器的登录(如不配置,将没办法使用 MySQL 中的用户名密码登录 CAS 服务器);其中 localmysql 为前面步骤创建的数据库名,app_user 为创建的表名,您需要替换为自己实际创建过程中的数据库名与表名。具体如下:

# JDBC配置

#数据库连接

cas.authn.jdbc.query[0].url=jdbc:mysql://localhost:3306/localmysql?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=UTC

#数据库dialect配置

cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect

#数据库用户名

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

#查询账号密码SQL,必须包含密码字段

cas.authn.jdbc.query[0].sql=select * from app_user where username=?

#指定上面的SQL查询字段名(必须)

cas.authn.jdbc.query[0].fieldPassword=password

增加配置项,增加单行属性配置,作为CAS服务器票证验证时返回给客户端的字段(如不配置,将不能获取数据表中其他字段,比如,前文中的 role 字段),如下:

#单行属性

#开启单行属性

cas.authn.attributeRepository.jdbc[0].singleRow=true

#设置数据库表和cas服务器之间查询结果的映射关系,具体与数据库的字段名为准

cas.authn.attributeRepository.jdbc[0].attributes.username=username

cas.authn.attributeRepository.jdbc[0].attributes.password=password

cas.authn.attributeRepository.jdbc[0].attributes.role=role

cas.authn.attributeRepository.jdbc[0].order=0

#返回所有属性

cas.authn.attributeRepository.jdbc[0].requireAllAttributes=true

#查询所有属性字段的SQL语句

cas.authn.attributeRepository.jdbc[0].sql=SELECT * FROM app_user WHERE {0}

#指定上面的SQL查询条件

cas.authn.attributeRepository.jdbc[0].username=username

注意:

a. cas.authn.attributeRepository.jdbc[0].attributes 参数只是查询结果的映射关系,需以实际表结构为准,此处的表结果为 username、password 和 role 三个字段。

b. cas.authn.attributeRepository.jdbc[0].sql 参数只是 CAS 查询数据库时使用到的 SQL 语句,自由性很大,使用其他正确的查询语句也是可行的。比如数据库中以 2 个关联表的形式存储数据时,SQL 语句可写为:

SELECT app_user.*,gl1.* FROM app_user,gl1 WHERE app_user.test = gl1.test and {0}

其中,app_user 表和 gl1 表通过 test 字段关联。

完整的 application.properties 如下:

#开启json注册服务

cas.serviceRegistry.initFromJson=true

#设置服务注册配置文件位置

cas.serviceRegistry.json.location=classpath:/services

# JDBC配置

#数据库连接

cas.authn.jdbc.query[0].url=jdbc:mysql://localhost:3306/localmysql?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=UTC

#数据库dialect配置

cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect

#数据库用户名

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

#查询账号密码SQL,必须包含密码字段

cas.authn.jdbc.query[0].sql=select * from app_user where username=?

#指定上面的SQL查询字段名(必须)

cas.authn.jdbc.query[0].fieldPassword=password

#单行属性

#开启单行属性

cas.authn.attributeRepository.jdbc[0].singleRow=true

#设置数据库表和cas服务器之间查询结果的映射关系,具体与数据库的字段名为准

cas.authn.attributeRepository.jdbc[0].attributes.username=username

cas.authn.attributeRepository.jdbc[0].attributes.password=password

cas.authn.attributeRepository.jdbc[0].attributes.role=role

cas.authn.attributeRepository.jdbc[0].order=0

#返回所有属性

cas.authn.attributeRepository.jdbc[0].requireAllAttributes=true

#查询所有属性字段的SQL语句

cas.authn.attributeRepository.jdbc[0].sql=SELECT * FROM app_user WHERE {0}

#指定上面的SQL查询条件

cas.authn.attributeRepository.jdbc[0].username=username

#数据库连接

cas.authn.attributeRepository.jdbc[0].url=jdbc:mysql://localhost:3306/localmysql?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=UTC

#数据库dialect配置

cas.authn.attributeRepository.jdbc[0].dialect=org.hibernate.dialect.MySQLDialect

#数据库用户名

cas.authn.attributeRepository.jdbc[0].user=root

#数据库用户密码

cas.authn.attributeRepository.jdbc[0].password=123456

#数据库事务自动提交

cas.authn.attributeRepository.jdbc[0].autocommit=false

#数据库驱动

cas.authn.attributeRepository.jdbc[0].driverClass=com.mysql.jdbc.Driver

#超时配置

cas.authn.attributeRepository.jdbc[0].idleTimeout=5000

至此,CAS 5.X 的配置完成 。