1 准备工具
2 配置环境 CAS 服务器信息 计算机名:IMC-Server 操作系统:Windows 2003 SP2 JDK:jdk1.6.0_21 Tomcat:apache-tomcat-6.0.30 浏览器:IE6 IP地址:10.12.21.45 CAS客户端信息 IP地址:10.12.21.140 Oracle数据库信息 IP地址:10.12.21.140 用户名:scott 密码:tiger 3 CAS验证服务器配置 1 解压cas-server-3.4.5-release.zip到磁盘(我的路径为D:\cas-server-3.4.5),进入D:\cas-server-3.4.5\modules文件夹下,把cas-server-webapp-3.4.5.war拷贝到Tomcat安装目录的(我的路径为D:\apache-tomcat-6.0.30)webapps文件夹下。为了方便在浏览器中浏览,把cas-server-webapp-3.4.5.war文件名修改为cas.war 2 运行Tomcat。在浏览器中输入http://10.12.21.45:8080/cas,显示登录界面。输入用户名和密码(用户名和密码相等即可),登录成功。这样最简单的CAS验证服务器搭配成功。
4 数据库验证方式4.1 密码已明文存在数据库中 1 复制D:\cas-server-3.4.5\modules下面所有jar包到D:\apache-tomcat-6.0.30\webapps\ cas\WEB-INF\lib下。数据库为Oracle,因此把Oracle驱动包也复制到lib文件夹下。注意删除重复的jar包。 2 打开D:\apache-tomcat-6.0.30\webapps\cas\WEB-INF\deployerConfigContext.xml文件 在<bean id="authenticationManager"节点上面添加数据源信息: <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"> <value> oracle.jdbc.driver.OracleDriver </value> </property> <property name="url"> <value> jdbc:oracle:thin:@10.12.21.140:1521:orcl </value> </property> <property name="username"> <value>scott</value> </property> <property name="password"> <value>tiger</value> </property> </bean>
|
在该文件中搜索“SimpleTestUsernamePasswordAuthenticationHandler” <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler"/> |
这是cas提供的最简单的验证方式,即用户名和密码相等即可登录成功。 现假设我们的登录用户名和密码存在于t_login表中,信息如下: 把上面的bean给注销掉,添加如下信息: <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"> <property name="sql" value="select password from t_login where username=?" /> <property name="dataSource" ref="dataSource" /> </bean> |
重启服务器,测试。当然我们还可以指定表和字段 <bean class="org.jasig.cas.adaptors.jdbc.SearchModeSearchDatabaseAuthenticationHandler" abstract="false" lazy-init="default" autowire="default"> <property name="dataSource" ref="dataSource" /> <property name="tableUsers" value="t_login" /> <property name="fieldUser" value="username"/> <property name="fieldPassword" value="password"/> </bean> | 4.2 密码已密文存在数据库中 以上的配置只适合密码已明文的方式存储在数据库中,但是实际中我们的密码都是经过加密的。下面演示下如果使用MD5加密密码。 首先配置MD5,该配置信息放在数据源配置的下面。 <bean id="passwordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder"> <constructor-arg value="MD5"/> </bean> |
然后修改上面的数据库验证配置,添加密码加密方式,修改后如下: <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"> <property name="sql" value="select password from t_login where username=?" /> <property name="dataSource" ref="dataSource" /> <property name="passwordEncoder" ref="passwordEncoder"/> </bean> | 4.3 使用自己编写的加密类 上面介绍了密码采用MD5加密的配置方式,下面介绍下如果使用我们自己编写的加密类。 1 新建一个Java项目,cas-server-core-3.4.5.jar包, 2 新建一个Java类,实现org.jasig.cas.authentication.handler.PasswordEncoder接口中的public String encode(String arg0)方法,这是用来对输入的密码进行加密,我这里命名为:PasswordEncrypt 3 在encode()方法中可以根据实际的加密方式编写代码。 package szy.cas.encrypt;
import java.security.MessageDigest; import org.jasig.cas.authentication.handler.PasswordEncoder;
/** * @author coolszy * @date Jan 21, 2011 */
public class PasswordEncrypt implements PasswordEncoder {
public String encode(String password) { try { MessageDigest alg = MessageDigest.getInstance("SHA-1"); alg.reset(); alg.update(password.getBytes()); byte[] hash = alg.digest(); String digest = ""; for (int i = 0; i < hash.length; i++) { int v = hash & 0xFF; if (v < 16) digest += "0"; digest += Integer.toString(v, 16).toUpperCase(); } return digest; } catch (Exception e) { e.printStackTrace(); return password; } } } |
编写完毕后,建议进行测试,避免错误发生。然后把该项目导出成jar包,并且把jar包拷贝到D:\apache-tomcat-6.0.30\webapps\cas\WEB-INF\lib下。然后修改上面添加的 <bean id="passwordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder"> <constructor-arg value="MD5"/> </bean> |
把class修改为我们的加密类,即 <bean id="passwordEncoder" class="szy.cas.encrypt.PasswordEncrypt"> <!-- <constructor-arg value="MD5"/> --> </bean> |
测试,成功。 5 修改界面5.1 修改验证通过后显示提示信息的界面 修改D:\apache-tomcat-6.0.30\webapps\cas\WEB-INF\view\jsp\default\ui\ casGenericSuccess.jsp页面,添加如下内容调转到指定页面 <% response.sendRedirect("http://10.12.21.139.:8080/client/index.action"); %> 5.2 定义自己的验证界面 cas给我们提供了一个"default" 界面,该界面比较简单,而且也不怎么漂亮,因此我们需要定制自己的验证界面。下面介绍一下如何设计自己的界面。 1 进入D:\apache-tomcat-6.0.30\webapps\cas\WEB-INF\view\jsp,把default文件夹复制一份在本目录下,这里我把文件夹修改为coolszy。 2 进入D:\apache-tomcat-6.0.30\webapps\cas\WEB-INF\view\jsp\coolszy\ui。在该目录下你将会看到如下文件: | 在浏览器跳转到用户想要访问的页面之前如果有警告信息,这个页面将会被显示。 | | 这个页面一般不会被显示,除非我们直接访问验证服务器的验证界面。http://10.12.21.45:8080/cas。 | | | | | | 如果用户想要访问的服务没有使用CAS,这个页面将会显示出来。 注意:如果我们所有的业务系统都使用了CAS,这个界面则会没有任何作用。 |
如果想修改界面,我建议我们首先熟悉里面所有的jsp页面。重点是casLoginView.jsp还有includes目录下的两个文件。 我们在修改时尽量不要修改forms和逻辑标签。除非我们比较熟悉他们。如果我们定义的页面中含有样式表,可直接修改D:\apache-tomcat-6.0.30\webapps\cas\themes\default目录下的cas.css文件。当然我们也可以自己创建一个css文件,个人建议也把文件放到D:\apache-tomcat-6.0.30\webapps\cas\themes中,可新建一个目录比如coolszy。接着我们要修改jsp页面中的引用路径。打开D:\apache-tomcat-6.0.30\webapps\cas\WEB-INF\view\jsp\ coolszy\ui\includes\top.jsp文件。找到如下代码: <spring:theme code="standard.custom.css.file" var="customCssFile" /> |
我们需要standard.custom.css.file的值。该值存在于 D:\apache-tomcat-6.0.30\webapps\cas\WEB-INF\classes\cas-theme-default.properties文件中。修改为我们的路径。 引用的图片也需要注意相对路径和绝对路径。 3 进入D:\apache-tomcat-6.0.30\webapps\cas\WEB-INF\classes目录,复制 default_views.properties,我这里重新命名为coolszy_views.properties。打开该文件,修改页面路径,我这里是把default全部替换为coolszy。 注意:该目录下存在很多messages_*.properties文件,主要是为了国际化。我把不需要的语言给删除掉。同时修改messages_zh_CN.properties文件中的信息,使得提示信息更加符合我们的需求。这个文件我是在Eclipse中修改的。我的Eclipse安装了PropertiesEditor插件。 4 打开D:\apache-tomcat-6.0.30\webapps\cas\WEB-INF\cas.properties文件,把 cas.viewResolver.basename=default_views 修改为 cas.viewResolver.basename=coolszy_views 5 启动服务器,测试下效果。有可能显示原来的界面,可尝试把D:\apache-tomcat-6.0.30\ work\Catalina 目录下的文件夹清空掉。 6 服务器端超时配置 打开D:\apache-tomcat-6.0.30\webapps\cas\WEB-INF\spring-configuration\目录中的 applicationContext.xml文件,修改如下部分信息: <bean id="httpClient" class="org.jasig.cas.util.HttpClient" p:readTimeout="5000" p:connectionTimeout="5000"/> |
修改我们所需要的超时时间。
7 HTTPS验证配置7.1 普通证书 注:如果电脑上没有设置环境变量JAVA_HOME,请设置完毕后再操作。 7.1.1 创建key 1 进入cmd。输入“cd\”来到系统根目录 2 输入命令 keytool -genkey -alias casserver -keyalg RSA -keypass changeit -storepass changeit -keystore server.keystore -validity 3600 |
注:参数 -validity 指证书的有效期(天),缺省有效期只有90天。其它参数含义请在cmd上输入keytool 回车即可看到。 在生成证书时会让你输入信息,其中“您的名字与姓氏是什么?”这个内容必须填写cas服务器所对应的域名或者服务器的计算机名,我这里使用计算机名: 这样在我们的C盘根目录下生成一个名为server.keystore的证书。 7.1.2 将证书导入的JDK的证书信任库中 1 导出证书,命令如下: keytool -export -trustcacerts -alias casserver -file server.cer -keystore server.keystore -storepass changeit |
注:server.keystore 为我们上一步生成的证书。 2 导入到证书信任库,命令如下: keytool -import -trustcacerts -alias casserver -file server.cer -keystore "C:\Program Files\Java\jdk1.6.0_21\jre\lib\security\cacerts" -storepass changeit |
注:JDK的路径根据你电脑安装的位置进行修改。另外如果你电脑中安装的JRE,还应执行如下命令: keytool -import -trustcacerts -alias casserver -file server.cer -keystore "C:\Program Files\Java\jre6\lib\security\cacerts" -storepass changeit |
3 顺便补充另外两个命令 列出所导入证书 keytool -list -v -keystore "C:\Program Files\Java\jdk1.6.0_21\jre\lib\security\cacerts" |
删除存在的证书 Keytool -delete -trustcacerts -alias casserver -keystore "C:\Program Files\Java\jdk1.6.0_21\jre\lib\security\cacerts" -storepass changeit |
注:如果提示输入密码,则输入:changeit 7.1.3 配置TOMCAT服务器 1 打开D:\apache-tomcat-6.0.30\conf\server.xml 文件,找到: <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" /> |
该内容默认是被注视掉。我们把该段修改为: <Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8443" minSpareThreads="5" maxSpareThreads="75" enableLookups="true" disableUploadTimeout="true" acceptCount="100" maxThreads="200" scheme="https" secure="true" SSLEnabled="true" clientAuth="false" sslProtocol="TLS" keystoreFile="C:\server.keystore" keystorePass="changeit"/> |
其中 keystoreFile为已经生成的服务器证书的地址 keystorePass为自定义的服务器证书的密码 7.1.4 测试 打开浏览器输入 如果出现如下警告信息,点击确定。 7.2 使用CA证书 在一些企业中会使用CA证书进行验证,本节讲解如何使用CA证书。 7.2.1 准备工作 使用如下命令把上一些的证书从CAS验证服务器和业务服务器上的JRE中删除 Keytool -delete -trustcacerts -alias casserver -keystore "C:\Program Files\Java\jdk1.6.0_21\jre\lib\security\cacerts" -storepass changeit
Keytool -delete -trustcacerts -alias casserver -keystore "C:\Program Files\Java\jre6\lib\security\cacerts" -storepass changeit | 7.2.2 创建key 在cas验证服务器输入命令 keytool -genkey -alias www.coolszy.com -keyalg RSA -keysize 2048 -keypass changeit -storepass changeit -keystore coolszy.jks -validity 3600 |
在生成证书时会让你输入信息,其中“您的名字与姓氏是什么?”这个内容同上: 这样在我们的C盘根目录下生成一个名为coolszy.jks的文件。 7.2.3 创建证书请求 命令: keytool -certreq -alias www.coolszy.com -file coolszy.csr -keystore coolszy.jks -keypass changeit -storepass changeit | 7.2.4 申请CA证书 1进入公司的CA证书申请网站 2点击“申请一个证书”——“高级证书申请”——“使用 base64 编码的 CMC 或 PKCS #10 文件提交 一个证书申请,或使用 base64 编码的 PKCS #7 文件续订证书申请。”—— “浏览要插入的文件”——选择“C:\coolszy.csr”——“提交”——“选择Base 64 编码”——“下载证书链”——保存certnew.p7b。 7.2.5 导入证书 keytool -import -trustcacerts -alias www.coolszy.com -file c:\certnew.p7b -keystore coolszy.jks -keypass changeit -storepass changeit | 7.2.6 CAS验证服务器端Tomcat配置 修改server.xml,开启开启https; <Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keyAlias="www.coolszy.com" keystoreFile="C:\coolszy.jks" keypass="changeit" /> | 8 业务系统配置8.1 JAVA版本8.1.1 添加jar包 解压cas-client-3.2.0-release.zip到磁盘上,我这里放在D盘中。并且把 D:\cas-client-3.2.0\modules目录中的所有jar包拷贝到我们业务系统中。注意删除重复的jar包。 8.1.2 导入证书 a.普通证书 我们需要把CAS验证服务器上生成的server.cer的证书导入到我们业务系统JDK上。 keytool -import -trustcacerts -alias casserver -file server.cer -keystore "C:\Program Files\Java\jdk1.6.0_21\jre\lib\security\cacerts" -storepass changeit |
b.使用CA证书 1进入公司的CA证书申请网站 2 点击“下载一个 CA 证书,证书链或 CRL” 3 编码方式选择“Base 64” 4 点击“下载 CA 证书”,保存到磁盘上 5 在命令控制台执行如下命令 keytool -import -keystore "C:\Program Files\Java\jre6\lib\security\cacerts" -file c:\certnew.cer -alias www.coolszy.com -storepass changeit
keytool -import -keystore "C:\Program Files\Java\jdk1.6.0_21\jre\lib\security\cacerts" -file c:\certnew.cer -alias www.coolszy.com -storepass changeit |
注意:根据JDK和JRE的安装路径进行相应的修改,如果没有安装JRE,则第一条命令不需要执行。
8.1.3 配置业务系统web.xml文件 在业务系统的web.xml中添加如下配置信息 <!-- CAS 客户端配置 --> <filter> <filter-name>CAS Authentication Filter</filter-name> <filter-class> org.jasig.cas.client.authentication.AuthenticationFilter </filter-class> <!-- CAS验证服务器地址,有域名填写域名 --> <init-param> <param-name>casServerLoginUrl</param-name> <param-value> https://10.12.21.46:8443/cas/login </param-value> </init-param> <init-param> <param-name>renew</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>gateway</param-name> <param-value>false</param-value> </init-param> <!-- 客户端应用服务器地址--> <init-param> <param-name>serverName</param-name> </init-param> </filter>
<!--负责Ticket校验--> <filter> <filter-name>CAS Validation Filter</filter-name> <filter-class> org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter </filter-class> <init-param> <param-name>casServerUrlPrefix</param-name> <param-value>https://IMC-Server:8443/cas/</param-value> </init-param> <init-param> <param-name>serverName</param-name> </init-param> <init-param> <param-name>useSession</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>redirectAfterValidation</param-name> <param-value>true</param-value> </init-param> </filter>
<filter> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <filter-class> org.jasig.cas.client.util.HttpServletRequestWrapperFilter </filter-class> </filter>
<filter> <filter-name>CAS Assertion Thread Local Filter</filter-name> <filter-class> org.jasig.cas.client.util.AssertionThreadLocalFilter </filter-class> </filter>
<filter-mapping> <filter-name>CAS Authentication Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
<filter-mapping> <filter-name>CAS Validation Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
<filter-mapping> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
<filter-mapping> <filter-name>CAS Assertion Thread Local Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> |
注:蓝色的部分根据实际情况做相应的修改。红色部分高亮IMC-Server是我们在生成证书时填写的“您的名字与姓氏是什么?”。8433为Tomcat上的SSL端口,在在现实中我们一般使用80端口。如果使用80端口,则端口号不需要写在配置文件上。 8.1.4 发布系统,测试。 如果出现如下警告信息,点击“继续浏览此网站(不推荐)。” 然后我们输入用户名和密码,登录成功。 8.2 C#版本9 获取登录用户信息9.1 获得登录用户名 在进行认证时,我们需要输入用户名和密码。怎么才能获得我们输入的用户名呢?通过下面的这两句代码,我们就可以得到用户名信息。 AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal(); String username = principal.getName();//获取用户名 |
9.2 获取更全面用户信息
之前我们假设用户的验证信息存储在t_login表中,表结构如下: 这张表中有三个字段。假设现在还存在另外一张表t_user。该表记录了用户的详细信息。我们可以通过上一节的方法获取username的值到t_user表中进行查询,这样我们就可以获得更详细的用户信息。 但是如果我们的t_login表的结构如下:
在登录成功后,我们希望在页面上显示NAME的值,这该怎么获取呢? 1首先,打开D:\apache-tomcat-6.0.30\webapps\cas\WEB-INF\deployerConfigContext.xml文件 找到如下配置信息: <!-- Bean that defines the attributes that a service may return. This example uses the Stub/Mock version. A real implementation may go against a database or LDAP server. The id should remain "attributeRepository" though. --> <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"> <constructor-arg index="0" ref="dataSource"/> <constructor-arg index="1" value="select * from t_login where {0}"/> <property name="queryAttributeMapping"> <map> <entry key="username" value="username"/> </map> </property> <property name="resultAttributeMapping"> <map> <entry key="username" value="username"/> <entry key="name" value="name"/> </map> </property> </bean> |
其中:通过阅读源码SingleRowJdbcPersonAttributeDao类构造函数需要提供两个参数,第一个是DataSource,第二个是SQL语句。 /** * Creates a new MultiRowJdbcPersonAttributeDao specifying the DataSource and SQL to use. * * @param ds The DataSource to get connections from for executing queries, may not be null. * @param attrList Sets the query attribute list * @param sql The SQL to execute for user attributes, may not be null. */ public SingleRowJdbcPersonAttributeDao(DataSource ds, String sql) { super(ds, sql); } |
此外,我们还需配置两个Map<String, Set<String>>类型的属性:queryAttributeMapping和resultAttributeMapping,其中queryAttributeMapping是存储sql用的查询条件属性。在上面的配置信息中sql=select * from t_login where {0},{0}是占位符,根据queryAttributeMapping中的内容进行组装,组装完毕后为select * from t_login where username= username,注意颜色与上面配置信息相对应。username这个不能修改,username根据数据库字段名称进行相应的修改。resultAttributeMapping使用键值对保存查询的结果,字段要与数据库中的字段进行对应。 2找到如下配置信息 <bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" /> |
修改成: <bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver"> <property name="attributeRepository" ref="attributeRepository"/> </bean> |
3找到如下配置信息: <bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl"> <property name="registeredServices"> <list> <bean class="org.jasig.cas.services.RegisteredServiceImpl"> <property name="id" value="0" /> <property name="name" value="HTTP" /> <property name="description" value="Only Allows HTTP Urls" /> <property name="serviceId" value="http://**" /> </bean>
<bean class="org.jasig.cas.services.RegisteredServiceImpl"> <property name="id" value="1" /> <property name="name" value="HTTPS" /> <property name="description" value="Only Allows HTTPS Urls" /> <property name="serviceId" value="https://**" /> </bean>
<bean class="org.jasig.cas.services.RegisteredServiceImpl"> <property name="id" value="2" /> <property name="name" value="IMAPS" /> <property name="description" value="Only Allows HTTPS Urls" /> <property name="serviceId" value="imaps://**" /> </bean>
<bean class="org.jasig.cas.services.RegisteredServiceImpl"> <property name="id" value="3" /> <property name="name" value="IMAP" /> <property name="description" value="Only Allows IMAP Urls" /> <property name="serviceId" value="imap://**" /> </bean> </list> </property> </bean> |
把bean里面的property都注释掉,即: <bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl"> <!-- <property name="registeredServices"> <list> <bean class="org.jasig.cas.services.RegisteredServiceImpl"> <property name="id" value="0" /> <property name="name" value="HTTP" /> <property name="description" value="Only Allows HTTP Urls" /> <property name="serviceId" value="http://**" /> </bean>
<bean class="org.jasig.cas.services.RegisteredServiceImpl"> <property name="id" value="1" /> <property name="name" value="HTTPS" /> <property name="description" value="Only Allows HTTPS Urls" /> <property name="serviceId" value="https://**" /> </bean>
<bean class="org.jasig.cas.services.RegisteredServiceImpl"> <property name="id" value="2" /> <property name="name" value="IMAPS" /> <property name="description" value="Only Allows HTTPS Urls" /> <property name="serviceId" value="imaps://**" /> </bean>
<bean class="org.jasig.cas.services.RegisteredServiceImpl"> <property name="id" value="3" /> <property name="name" value="IMAP" /> <property name="description" value="Only Allows IMAP Urls" /> <property name="serviceId" value="imap://**" /> </bean> </list> </property> --> </bean> |
如果不注释掉,我们就不能获得我们需要的信息。 4修改D:\apache-tomcat-6.0.30\webapps\cas\WEB-INF\view\jsp\protocol\2.0\casServiceValidationSuccess.jsp 在server验证成功后,这个页面负责生成与客户端交互的xml信息,原装内容如下: <%@ page session="false" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %><cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'> <cas:authenticationSuccess> <cas:user> ${fn:escapeXml(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.id)} </cas:user> <c:if test="${not empty pgtIou}"> <cas:proxyGrantingTicket> ${pgtIou} </cas:proxyGrantingTicket> </c:if> <c:if test="${fn:length(assertion.chainedAuthentications) > 1}"> <cas:proxies> <c:forEach var="proxy" items="${assertion.chainedAuthentications}" varStatus="loopStatus" begin="0" end="${fn:length(assertion.chainedAuthentications)-2}" step="1"> <cas:proxy>${fn:escapeXml(proxy.principal.id)}</cas:proxy> </c:forEach> </cas:proxies> </c:if> </cas:authenticationSuccess> </cas:serviceResponse> |
在默认的casServiceValidationSuccess.jsp中,只包括用户名,并不提供其它的属性信息,因此需要对页面进行相应的修改,如下(红色为新添加部分): <%@ page session="false"%> <%@ page import="java.net.URLEncoder"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%> <cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'> <cas:authenticationSuccess> <cas:user>${fn:escapeXml(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.id)}</cas:user> <c:if test="${not empty pgtIou}"> <cas:proxyGrantingTicket>${pgtIou}</cas:proxyGrantingTicket> </c:if> <c:if test="${fn:length(assertion.chainedAuthentications) > 1}"> <cas:proxies> <c:forEach var="proxy" items="${assertion.chainedAuthentications}" varStatus="loopStatus" begin="0" end="${fn:length(assertion.chainedAuthentications)-2}" step="1"> <cas:proxy>${fn:escapeXml(proxy.principal.id)}</cas:proxy> </c:forEach> </cas:proxies> </c:if> <c:if test="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes)>0}"> <cas:attributes> <c:forEach var="attr" items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}" varStatus="loopStatus" begin="0" end="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes)-1}" step="1"> <c:set var="key" value="${fn:escapeXml(attr.key)}" scope="request"></c:set> <c:set var="value" value="${fn:escapeXml(attr.value)}" scope="request"></c:set> <% if(null==request.getAttribute("value")) { %> <cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}> <% } else { %> <cas:${key}><%=URLEncoder.encode((String)request.getAttribute("value"),"UTF-8")%></cas:${key}> <% } %> </c:forEach> </cas:attributes> </c:if> </cas:authenticationSuccess> </cas:serviceResponse> |
注1:在添加的代码中我加入了jsp代码,熟悉EL表达式的可以修改为EL表达式,那样更符合规范。 注2:if(null==request.getAttribute("value"))是对取得值判断是否为空,具体是否有作用,我自己也不清楚。 注3:<%=URLEncoder.encode((String)request.getAttribute("value"),"UTF-8")%>主要是针对中文进行编码。如果不进行编码,业务层获得的值是乱码。 5使用Java语言开发的业务系统可通过如下方式得到我们需要的信息: AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal(); String username = principal.getName();//获取用户名 Map<String, Object> attributes = principal.getAttributes(); String name=attributes.get("name").toString(); name=URLDecoder.decode(name,"UTF-8"); | 10 保存用户认证日志 1在Oracle数据库中创建表,SQL脚本如下(建议一行一行执行): CREATE TABLE "COM_AUDIT_TRAIL" ( "AUD_USER" VARCHAR2(100) NOT NULL ENABLE, "AUD_CLIENT_IP" VARCHAR(15) NOT NULL ENABLE, "AUD_SERVER_IP" VARCHAR(15) NOT NULL ENABLE, "AUD_RESOURCE" VARCHAR2(100) NOT NULL ENABLE, "AUD_ACTION" VARCHAR2(100) NOT NULL ENABLE, "APPLIC_CD" VARCHAR2(5) NOT NULL ENABLE, "AUD_DATE" TIMESTAMP NOT NULL ENABLE ); ALTER TABLE "COM_AUDIT_TRAIL" ADD CONSTRAINT "COM_AUDIT_TRAIL_PK" PRIMARY KEY ( "AUD_USER", "AUD_CLIENT_IP", "AUD_SERVER_IP", "AUD_RESOURCE", "AUD_ACTION", "APPLIC_CD", "AUD_DATE" ) ENABLE;
CREATE TABLE "COM_STATISTICS" ( "STAT_SERVER_IP" VARCHAR2(15) NOT NULL ENABLE, "STAT_DATE" DATE NOT NULL ENABLE, "APPLIC_CD" VARCHAR2(5) NOT NULL ENABLE, "STAT_PRECISION" VARCHAR2(6) NOT NULL ENABLE, "STAT_COUNT" NUMBER NOT NULL ENABLE, "STAT_NAME" VARCHAR2(100) );
ALTER TABLE "COM_STATISTICS" ADD CONSTRAINT "COM_STATISTICS_PK" PRIMARY KEY ( "STAT_SERVER_IP", "STAT_DATE", "APPLIC_CD", "STAT_PRECISION", "STAT_NAME" ) ENABLE;
CREATE INDEX "COM_AUDIT_TRAIL_DATE_I" ON "COM_AUDIT_TRAIL" ("AUD_DATE");
CREATE INDEX "COM_AUDIT_TRAIL_CLIENT_DATE_I" ON "COM_AUDIT_TRAIL" ("AUD_CLIENT_IP", "AUD_DATE");
CREATE INDEX "COM_AUDIT_TRAIL_USER_DATE_I" ON "COM_AUDIT_TRAIL" ("AUD_USER", "AUD_DATE");
CREATE INDEX "COM_AUDIT_TRAIL_ACTION_DATE_I" ON "COM_AUDIT_TRAIL" ("AUD_ACTION", "AUD_DATE");
CREATE INDEX "COM_STATISTICS_DATE_I" ON "COM_STATISTICS" ("STAT_DATE");
CREATE INDEX "COM_STATISTICS_NAME_DATE_I" ON "COM_STATISTICS" ("STAT_NAME", "STAT_DATE"); |
2打开D:\apache-tomcat-6.0.30\webapps\cas\WEB-INF\deployerConfigContext.xml文件,在进行数据库验证方式(参考4.1)时,我们配置过dataSource: <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"> <value> oracle.jdbc.driver.OracleDriver </value> </property> <property name="url"> <value> jdbc:oracle:thin:@10.12.21.140:1521:orcl </value> </property> <property name="username"> <value>scott</value> </property> <property name="password"> <value>tiger</value> </property> </bean> |
我们把该段给注释掉,然后在添加如下配置信息: <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" p:driverClass="oracle.jdbc.driver.OracleDriver" p:jdbcUrl="jdbc:oracle:thin:@10.12.21.140:1521:orcl" p:user="scott" p:password="tiger" p:initialPoolSize="2" p:minPoolSize="2" p:maxPoolSize="16" p:maxIdleTimeExcessConnections="25200" p:checkoutTimeout="1800" p:acquireIncrement="2" p:acquireRetryAttempts="2" p:acquireRetryDelay="1000" p:idleConnectionTestPeriod="30" p:preferredTestQuery="select 1 from dual" /> |
3复制D:\apache-tomcat-6.0.30\webapps\cas\WEB-INF\unused-spring-configuration\ auditTrailContext.xml文件到D:\apache-tomcat-6.0.30\webapps\cas\WEB-INF\ spring-configuration目录下,打开该文件,删除里面的内容,添加如下信息: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
<description> Configuration file for the Inspektr package which handles auditing for Java applications. If enabled this should be modified to log audit and statistics information the same way your local applications do. The default is currently to log to the console which is good for debugging/testing purposes. </description>
<aop:aspectj-autoproxy/>
<bean id="auditTrailManagementAspect" class="com.github.inspektr.audit.AuditTrailManagementAspect"> <!-- String applicationCode --> <constructor-arg index="0" value="CAS" />
<!-- PrincipalResolver auditablePrincipalResolver --> <constructor-arg index="1" ref="auditablePrincipalResolver" />
<!-- List<AuditTrailManager> auditTrailManagers --> <constructor-arg index="2"> <list> <bean class="com.github.inspektr.audit.support.ConsoleAuditTrailManager" /> <!-- Uncomment following for writing logs to database via JDBC. See below for definition of auditManager bean. --> <ref local="auditManager" /> </list> </constructor-arg>
<!-- Map<String,AuditActionResolver> auditActionResolverMap --> <constructor-arg index="3"> <map> <entry key="AUTHENTICATION_RESOLVER"> <ref local="authenticationActionResolver" /> </entry> <entry key="CREATE_TICKET_GRANTING_TICKET_RESOLVER"> <ref local="ticketCreationActionResolver" /> </entry> <entry key="DESTROY_TICKET_GRANTING_TICKET_RESOLVER"> <bean class="com.github.inspektr.audit.spi.support.DefaultAuditActionResolver" /> </entry> <entry key="GRANT_SERVICE_TICKET_RESOLVER"> <ref local="ticketCreationActionResolver" /> </entry> <entry key="GRANT_PROXY_GRANTING_TICKET_RESOLVER"> <ref local="ticketCreationActionResolver" /> </entry> <entry key="VALIDATE_SERVICE_TICKET_RESOLVER"> <ref local="ticketValidationActionResolver" /> </entry> </map> </constructor-arg>
<!-- Map<String,AuditResourceResolver> auditResourceResolverMap --> <constructor-arg index="4"> <map> <entry key="AUTHENTICATION_RESOURCE_RESOLVER"> <bean class="org.jasig.cas.audit.spi.CredentialsAsFirstParameterResourceResolver" /> </entry> <entry key="CREATE_TICKET_GRANTING_TICKET_RESOURCE_RESOLVER"> <ref local="returnValueResourceResolver" /> </entry> <entry key="DESTROY_TICKET_GRANTING_TICKET_RESOURCE_RESOLVER"> <ref local="ticketResourceResolver" /> </entry> <entry key="GRANT_SERVICE_TICKET_RESOURCE_RESOLVER"> <bean class="org.jasig.cas.audit.spi.ServiceResourceResolver" /> </entry> <entry key="GRANT_PROXY_GRANTING_TICKET_RESOURCE_RESOLVER"> <ref local="returnValueResourceResolver" /> </entry> <entry key="VALIDATE_SERVICE_TICKET_RESOURCE_RESOLVER"> <ref local="ticketResourceResolver" /> </entry> </map> </constructor-arg> </bean> <!----> <bean id="auditablePrincipalResolver" class="org.jasig.cas.audit.spi.TicketOrCredentialPrincipalResolver"> <constructor-arg index="0" ref="ticketRegistry" /> </bean>
<bean id="authenticationActionResolver" class="com.github.inspektr.audit.spi.support.DefaultAuditActionResolver"> <!-- String successSuffix --> <constructor-arg index="0" value="_SUCCESS" />
<!-- String failureSuffix --> <constructor-arg index="1" value="_FAILED" /> </bean>
<bean id="ticketCreationActionResolver" class="com.github.inspektr.audit.spi.support.DefaultAuditActionResolver"> <!-- String successSuffix --> <constructor-arg index="0" value="_CREATED" />
<!-- String failureSuffix --> <constructor-arg index="1" value="_NOT_CREATED" /> </bean>
<bean id="ticketValidationActionResolver" class="com.github.inspektr.audit.spi.support.DefaultAuditActionResolver"> <!-- String successSuffix --> <constructor-arg index="0" value="D" />
<!-- String failureSuffix --> <constructor-arg index="1" value="_FAILED" /> </bean>
<bean id="returnValueResourceResolver" class="com.github.inspektr.audit.spi.support.ReturnValueAsStringResourceResolver" />
<bean id="ticketResourceResolver" class="org.jasig.cas.audit.spi.TicketAsFirstParameterResourceResolver" />
<!-- Uncomment following beans for JDBC support. Assumes there is a dataSource bean that defines a valid JDBC data source. -->
<bean id="inspektrTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource" />
<bean id="inspektrTransactionTemplate" class="org.springframework.transaction.support.TransactionTemplate" p:transactionManager-ref="inspektrTransactionManager" p:isolationLevelName="ISOLATION_READ_COMMITTED" p:propagationBehaviorName="PROPAGATION_REQUIRED" />
<bean id="auditManager" class="com.github.inspektr.audit.support.JdbcAuditTrailManager"> <constructor-arg index="0" ref="inspektrTransactionTemplate" /> <property name="dataSource" ref="dataSource" /> </bean>
</beans> |
4重启服务器进行测。 题外:有个日志信息,我们可以编写一个小系统,方便我们进行日志的查询。 11 集成AD验证方式11.1 配置文件 注:把原来的配置信息打个压缩包进行备份。下面我使用cas提供的最原始的jar包讲解如何集成AD。Tomcat服务器也使用最干净的配置。 参考资料: 注:配置信息根据实际情况进行相应的修改。 1 打开D:\apache-tomcat-6.0.30\webapps\cas\WEB-INF\deployerConfigContext.xml文件,在<beans>节点下添加如下配置信息: <bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource"> <property name="anonymousReadOnly" value="false" /> <property name="userDn" value="CN=lookupAcct,CN=Users,DC=coolszy,DC=net" /> <property name="password" value="secret" /> <property name="pooled" value="true" /> <property name="urls"> <list> <value>ldap://ad.coolszy.net/</value> </list> </property> <property name="baseEnvironmentProperties"> <map> <entry> <key> <value>java.naming.security.authentication</value> </key> <value>simple</value> </entry> </map> </property> </bean> |
2找到 <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" /> |
注释该局,替换成 <bean class="org.jasig.cas.adaptors.ldap.BindLdapAuthenticationHandler"> <property name="filter" value="sAMAccountName=%u" /> <property name="searchBase" value="DC=coolszy,DC=net" /> <property name="contextSource" ref="contextSource" /> <property name="ignorePartialResultException" value="yes" /> </bean> |
3添加jar包 我们需要导入三个jar包: spring-ldap-core-tiger-1.3.0.RELEASE.jar spring-ldap-core-1.3.0.RELEASE.jar cas-server-support-ldap-3.4.3.1.jar 11.2 获取更多认证信息 在9.2中介绍了如何获得表中更多信息,下面讲解如何获得AD中的信息。 把9.2中的attributeRepository节点修改为如下配置,其它配置同上。 <bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate"> <constructor-arg ref="contextSource" /> <property name="ignorePartialResultException" value="true" /> </bean> <bean id="attributeRepository" class="org.jasig.services.persondir.support.ldap.LdapPersonAttributeDao"> <property name="contextSource" ref="contextSource" /> <property name="baseDN" value="DC=jnpc,DC=net" /> <property name="requireAllQueryAttributes" value="true" /> <property name="ldapTemplate" ref="ldapTemplate" /> <property name="queryAttributeMapping"> <map> <entry key="username" value="sAMAccountName" /> </map> </property> <property name="resultAttributeMapping"> <map> <entry key="sAMAccountName" value="sAMAccountName" /> <entry key="name" value="name" /> </map> </property> </bean> |
SSO单点登陆CAS配置手册.doc
(422 KB, 下载次数: 0, 售价: 2 云币)
|