CAS 实现单点登录

来源:互联网 发布:cad软件培训 编辑:程序博客网 时间:2024/04/29 23:51

1.     概述

1.1背景

      单点登录是必须的,实现方式颇多,这里就说使用CAS的实现方式。使用CAS实现SSO,网络上说明很多,大部分都是从制作证书开始,而实际上是可以不使用HTTPS验证,这样更方便。

      单点登录的原理是通过拦截你设定的URL,并跳转到你指定的CAS SERVER登录页,当你登录成功后,带着TICKET,返回到你打开的URL。然后你就可以一票在手,畅通无阻。

      网上有个家伙用旅游的套票来解释单点登录,非常形象。当你到达一个旅游区门口,你可以买一个套票,套票规定你可以游览N个景点,进入这些景点的时候,你不需要再买票,也就实现了单点登录。

      同时,也可以借用这个比喻说明一下单点注销。当你打开一个应用A时,单击了注销按钮,跳转到http://hostname:port/cas/logout或者https://hostname:port/cas/logout,系统显示注销成功。此时,IE窗口没有关闭,你继续打开应用A,仍然没有注销成功,不需要登录。这就相当于你已经在旅游景点内,即使你把套票撕毁了,你仍然可以继续参观这个景点,不会把你驱逐出去。但是,你再也进不了其它的景点了。

      那么怎么实现立即生效的注销呢?或者这种方式是否就满足我们的需求呢?

1.2环境

      Windows XPJDK1.6.03Tomcat6.0.20

注意:配置好环境变量。

1.3下载资源

服务器端:http://www.ja-sig.org/downloads/cas

当前最新版本是3.3.4测试安装的版本为3.3.3

cas-server-3.3.3-release.zip

客户端:https://www.ja-sig.org/svn/cas-clients/

      cas-client-2.0.11.zip            JAVA支持单点登录

      cas-client-3.1.8-release.zip          JAVA支持单点注销

      dotnet-client                               DOTNET支持类

      phpcas                                      PHP支持

      

注意:同时要下载源代码,部分功能需要修改源代码,重新做包。

2.配置CAS SERVER

CAS SERVER目录介绍。

2.1简单配置

      把你下载cas-server解压,进入cas-server-3.3/modules,复制cas-server-webapp-3.3.wartomcat/webapps下,修改名称为cas.war,方便使用,原来的名字太长了。然后启动IE,输入http://localhost:8080/cas检验是否可以访问,如果可以,则输入相同的用户名和密码,比如cas/cas,测试是否能登录。

      如果你对安全性要求不高且急不可待,这个时候就可以直接进行CAS CLIENT的配置。

 

2.2数据库验证配置

      简单配置后,可以使用相同的用户名和密码,进行登录。这个不实际,可以通过配置实现连接自己的数据库进行配置。这里有个前提,就是所有系统需要使用相同的用户表和密码加密方法,可以使用CAS自带的加密方法(/org/jasig/cas/authentication/handler/DefaultPasswordEncoder.class)或自己用JAVA写的加密方法。

      进入目录tomcat/webapps/cas/WEB-INF,打开文件deployerConfigContext.xml,找到类似下面的代码:

注意cas-server根据版本不同文件的路径或BEAN位置可能不同逐个文件夹找下。

 

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

 

这是默认的方法。同时还有两种可选,如下:

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

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

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

             </bean>

/************************************************************************/

<bean class="org.jasig.cas.adaptors.jdbc.SearchModeSearchDatabaseAuthenticationHandler"

                      abstract="false" lazy-init="default" autowire="default" dependency-check="default">

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

                      <property name="tableUsers" value="tbUser" />

                      <property name="fieldUser" value="u_userid"/>

                      <property name="fieldPassword" value="u_password"/>

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

                      </bean>

以上两种方式都经过测试。另外,也可以写出自己的方法验证,修改BEANCLASS属性即可。如果没有密码没有加密,则可以把参数<property name="passwordEncoder" ref="passwordEncoder"/>去掉。

 

下面针对最下面的方法进行说明。

      看它的属性,还需要定义两个BEAN,数据源和加密,如下:

      <bean id="casDataSource" class="org.apache.commons.dbcp.BasicDataSource">

     <!—SQL SERVER

                   <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"></property>

                   <property name="url" value="jdbc:sqlserver://10.7.3.90:1433;DatabaseName=itacc"></property>

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

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

           

     --> 

<!--ORACLEà   

     <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>

             <property name="url" value="jdbc:oracle:thin:@10.7.3.90:1521:orcl"></property>

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

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

 

             <property name="maxActive" value="100"></property>

             <property name="maxIdle" value="30"></property>

             <property name="maxWait" value="500"></property>

             <property name="defaultAutoCommit" value="true"></property>     

     </bean> 

 

  <!—加密à

     <bean id="passwordEncoder" 

       class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder" autowire="byName">     

       <constructor-arg value="MD5"/> 

</bean>

由于CAS-SERVER.WAR默认没有采用数据库加密,所以部分JAR包,没有引入,下面这些需要复制到webapps/cas/WEB-INF/lib里面:

Cas-server-support-jdbc-3.3.3.jar

Cas-server-support-ldap-3.3.3.jar

Commons-dbcp.jar

Commons-pool.jar

Org.springframework.jdbc-3.0.0.M4.jar       //spring要根据自己的版本选择

Org.springframework.transaction-3.0.0.M4.jar

Sqljdbc.jar                                                            //数据库连接JAR,根据自己的复制

Oraclejdbc.jar

完成以后,用户表数据准备好后,可以运行http://localhost:8080/cas进行登录测试。这个时候很容易出现错误,多数是因为JAR包问题,注意查看tomcat/logs日志文件,进行检查,问题很容易解决。

2.3参数配置

      这里只说明一下我涉及到的参数,可能有更多参数,目前还没有用到。

      1tomcat/webapps/cas/WEB-INF/deployerConfigContext.xml

<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"

                                  p:httpClient-ref="httpClient"/>

      增加参数p:requireSecure="false",是否需要安全验证,即HTTPSfalse为不采用,加上去之后如下:

<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"

                                  p:httpClient-ref="httpClient" p:requireSecure="false"/>

 

      2Tomcat 6.0/webapps/cas/WEB-INF/spring-configuration/

ticketGrantingTicketCookieGenerator.xml

<bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"

             p:cookieSecure="true"

             p:cookieMaxAge="-1"

             p:cookieName="CASTGC"

             p:cookiePath="/cas" />

参数p:cookieSecure="true",同理为HTTPS验证相关,TRUE为采用HTTPS验证,与deployerConfigContext.xml的参数保持一致。

参数p:cookieMaxAge="-1",简单说是COOKIE的最大生命周期,-1为无生命周期,即只在当前打开的IE窗口有效,IE关闭或重新打开其它窗口,仍会要求验证。可以根据需要修改为大于0的数字,比如3600等,意思是在3600秒内,打开任意IE窗口,都不需要验证。

 

warnCookieGenerator.xml

<bean id="warnCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"

             p:cookieSecure="true"

             p:cookieMaxAge="-1"

             p:cookieName="CASPRIVACY"

             p:cookiePath="/cas" />

两个参数与上面同理。

 

3TICKET的生命周期也可以在web.xml加这个参数实现:

<!-- Timeout for granting tickets -->

   <context-param>

       <param-name>edu.yale.its.tp.cas.grantingTimeout</param-name>

       <param-value>7200</param-value>

   </context-param>

2.4HTTPS验证配置

      证书的制作使用keytool工具,进入CMD,输入keytool,回车测试,如果出现帮助,则说明环境变量配置正确,如果没有,则配置PATH,加入%JAVA_HOME%/BIN

下面开始制作,先找好存放证书的位置:

(1)      keytool -genkey -alias tomcatcas -keystore tomcatcas -keyalg RSA -validity 3666

这一步是制作密钥库。

注意:名字与姓氏要输入主机名或域名或localhost,不能随意输入。密码为自己设定。下面的密码直接回车。

2keytool -export -alias tomcatcas -keystore tomcatcas -file tomcatcas.crt

      这一步是把密钥库导出为证书文件。

注意:密码为上一步设定的密码。

 

3keytool -import -alias tomcatcas -file tomcatcas.crt

-keystore %JAVA_HOME%/jre/lib/security/cacerts

        这一步是把证书导入TOMCAT

后面的路径为TOMCAT使用的JRE路径,JDK1.6安装有两个目录JDK1.6JRE1.6TOMCAT6.0只要JRE1.6即可,通常在安装时,也都是默认到JRE1.6,这时要输入%JRE_HOME%/lib/security/cacerts,这个地方必须要确认准确。

        注意:这里需要输入密码,此密码不是前面设定的密码,是系统默认的密码changeit

 

4)配置tomcat6.0/conf/server.xml

<!--

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"

              maxThreads="150" scheme="https" secure="true"

              clientAuth="false" sslProtocol="TLS"

              />

à

加入密钥库文件和密码(前面设定的密码),修改为

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"

              maxThreads="150" scheme="https" secure="true"

              clientAuth="false" sslProtocol="TLS"

              keystoreFile="d:/data/tomcatcas.keystore"

              keystorePass="123456"

              />

注意:密钥库文件的要放到安全的位置,不能被随意移动。

完成后,可重启TOMCAT,进行测试。

2.5自定义页面                 

      CAS页面文件放在Tomcat 6.0/webapps/cas/WEB-INF/view/jsp中,页面配置文件在Tomcat 6.0/webapps/cas/WEB-INF/classes中,比如default_views.properties,在这里指定登录用哪个页面,注销用哪个页面等等。

Tomcat 6.0/webapps/cas/WEB-INF/cas.properties文件指定使用哪个皮肤页面。

      下面开始操作:

      1、进入Tomcat 6.0/webapps/cas/WEB-INF/view/jsp,复制default文件夹,并改名,再复制回来,如myth

      2、进入Tomcat 6.0/webapps/cas/WEB-INF/classes,复制default_views.properties,并改名再复制回来,如myth_views.properties。打开文件,把里面的目录../jsp/default/ui修改为自己的路径,如../jsp/myth/ui

      3、进入Tomcat 6.0/webapps/cas/WEB-INF,打开cas.properties文件,修改

cas.viewResolver.basename=myth_views

完成以上3步后打开IE进入http://localhost:8080/cas进行测试如果成功则进行下一步

注意:文件中logout使用的类。

4、修改页面样式

 

 

最后一点说明,Tomcat 6.0/webapps/cas/WEB-INF/cas-server.xml中,有个BEAN

      <bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver"

             p:order="0">

             <property name="basenames">

                    <list>

                           <value>${cas.viewResolver.basename}</value>

                           <value>protocol_views</value>

                    </list>

             </property>

      </bean>

这个不要修改否则出现http code 500 for url

3.配置JAVA CLIENT

3.1HTTPS验证

      1、把casclient.jarcas-client-3.1.8.jar复制到你的jsp工程的WEB-INF/lib里;

      2、修改web.xml,增加下面的代码:

<!--用于单点退出-->

<listener> <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>

</listener>

<filter>

   <filter-name>CAS Single Sign Out Filter</filter-name>

   <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>

</filter>

<!--用于单点登录-->

<filter>

<filter-name>CAS Filter</filter-name>

<filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>

<!—下面两个为验证地址,即cas server的地址,如果使用https验证,地址为https://hostname:8443字样- ->

   <init-param>

     <param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>

      <param-value>http://c7.byd.com:8080/cas/login</param-value>

   </init-param>

   <init-param>

      <param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>

      <param-value>http://c7.byd.com:8080/cas/serviceValidate</param-value>

</init-param>

<!—本工程的URL,被拦截的地址- ->

   <init-param>

      <param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>

      <param-value>localhost:8080</param-value>

   </init-param>

</filter>

 

<filter-mapping>

   <filter-name>CAS Single Sign Out Filter</filter-name>

   <url-pattern>/*</url-pattern>

</filter-mapping>

 

<filter-mapping>

   <filter-name>CAS Filter</filter-name>

   <url-pattern>/*</url-pattern>

</filter-mapping>

      3、在页面获得验证返回的用户

用户可以通过以下方式,从JSPservlet中获取通过认证的用户名:

String username = (String)session.getAttribute(edu.yale.its.tp.cas.client.filter.CASFilter.CAS_FILTER_USER);

 

获得更完整的受认证用户信息对象CASReceipt Java Bean,可以使用以下语句:

CASReceipt  receipt = (CASReceipt )session.getAttribute(edu.yale.its.tp.cas.client.filter.CASFilter.CAS_FILTER_RECEIPT);

 

      

      完成以上后,进行测试。出现错误时,请查看tomcat/logs文件解决。

3.2HTTP验证

      1、修改casclient.jar中文件,如图:

      

      2、重新做jar包,复制到工程目录

      

      完成后,做好测试。登录成功后的样子,如下图:

4.配置DOTNET CLIENT

      1、把DotNetCasClient.cs复制到DotNet项目

 

 

      2、新建loginPage.aspxPage_Load加入代码

DotNetCASClient.DotNetCASClientServiceValidate client = new DotNetCASClient.DotNetCASClientServiceValidate();

           String userId = client.Authenticate(Request, Response, false);

           if (userId.Equals("failed"))

           {

               //Handle the auth failure...

           }

           else

           {

               Session[DotNetCASClient.SessionHandle.getUserSession()] = userId;

               FormsAuthentication.RedirectFromLoginPage(userId, false);

           }

注意:FormsAuthentication.RedirectFromLoginPage这个方法。

      

 

      3、在Default.aspxPage_Load内加入获得用户的代码:

      4、修改web.config文件

<?xml version="1.0" encoding="utf-8"?>

<configuration>

        <appSettings>

                  <add key="casLoginURL" value="http://c7.byd.com:8080/cas/login" />

                  <add key="casValidateURL" value="http://c7.byd.com:8080/cas/serviceValidate" />

                  <add key="serviceURL" value="http://localhost/dq/Default.aspx" />

        </appSettings>

        <connectionStrings/>

 

   <system.web>

                  <authentication mode="Forms" >

                           <forms name="casauth" loginUrl="loginPage.aspx" />

                  </authentication>

                  <authorization>

                           <deny users="?" />

                  </authorization>

        </system.web>

</configuration>

      

      

      完成后,运行测试,效果如下图:

Cas为用户名。

5.配置PHP CLIENT

6.如何实现单点注销