重庆工商大学网站群建设项目实施报告  
 
   文章来源:      发布时间:2016-12-27 10:35:18      阅读次数:
 

重庆工商大学网站群建设项目

实施报告

重庆满阳科技有限公司

2014年10月20日

目  录

目  录.... 2

一、培训安排.... 5

(一)培训目的... 5

(二)培训内容... 5

(三)培训人员... 5

(四)培训时间... 5

(五)培训地点... 5

(六)培训对象... 5

(七)参与人员签到表... 5

二、环境搭建.... 6

(一)环境支持... 7

三、VSB9安装.... 7

(一)部署安排... 7

(二)部署说明... 8

(1)       VSB9管理机... 8

(2)       VSB9发布机1、2. 8

(3)       VSB9发布机3、4. 9

(4)       Oracle数据库服务器... 9

(三)服务器及数据库管理账号密码... 10

(1)       VSB9管理机... 10

(2)       VSB9发布机1、2. 10

(3)       VSB9发布机3、4. 11

(4)       Oracle数据库服务器... 11

(四)系统截图... 11

(1)       登录入口... 12

(2)       系统版本... 12

(3)       软件环境... 13

(4)       服务器参数... 13

(5)       安全管理... 14

(6)       备份恢复... 15

(7)       网站管理... 16

四、网站迁移及首页设计.... 16

(一)二级网站迁移... 16

(1)       系统截图... 17

(2)       迁移登记表... 17

(二)学校主页设计及安排... 22

五、与数字校园系统集成.... 24

(一)集成方案... 24

(1)       CAS证书导入... 24

(2)       CAS应用接口... 26

(二)集成过程... 26

(1)       JAVA系统SSO集成方式... 26

(2)       PHP系统SSO集成方式... 36

(3)       ASP.NET系统SSO集成方式... 49

(4)       ASP系统SSO集成方式... 52

(三) 数据集成使用及效果... 54

1、建立中间表... 54

2、 静态登录组件代码... 56

3、 登陆组件样式配置... 69

4、 登陆组件代码... 71

5、 用户数据集成使用... 84

1、复制已经修改好的前台的web.xml. 84

2、快速发布整个页面... 84

3、 重启服务... 84

1、 发布对内文章... 85

 

 

 

 

 

 

 

 

 

一、培训安排

(一)培训目的

参与人员能够独立维护并熟悉使用系统的各项功能。

(二)培训内容

了解系统整体架构,掌握创建网站、网站管理、系统管理、文章采集、模板更换、文章更新、备份等常见应用功能。

(三)培训人员

杨含(西安博达软件有限公司)、刘松(重庆满阳科技有限公司)

(四)培训时间

2014年6月12日至2014年6月14日(为期3天)

(五)培训地点

重庆工商大学数字中心培训会议室

(六)培训对象

数字化校园管理中心及相关维护使用人员

(七)参与人员签到表

二、环境搭建

(一)环境支持

 

服务器

硬件建议配置

操作系统

应用服务器

2GHz以上CPU主频、2G以上内存、硬盘剩余空间200G以上、100M-1000M以太网卡

Windows server   2003/2008、Linux、Solaris、Unix

数据库服务器

2GHz以上CPU主频、4G以上内存、硬盘剩余空间200G以上、100M-1000M以太网卡

Windows server   2003/2008、Linux、Solaris、Unix

客户端

1GHz以上CPU主频、1GB以上内存、80G以上硬盘。浏览器:IE6.0以上版本

Windows   2000/XP/Vista/7

数据库系统:

√支持SQL Server、Oracle、DB2、Sybase、MySQL、Access、Kingbase等主流关系型数据库。

应用服务器:

√支持IIS、Tomcat、Apache、Resin、WebSphere、WebLogic、Jboss等应用服务中间件。

√支持JDK1.4级以上版本。

三、VSB9安装

(一)部署安排

部署人员:刘松(重庆满阳科技有限公司)、周立业(西安博达软件有限公司)

部署时间:2014年06月15日至2014年06月17日

完成情况:已按要求部署并完成调试。

(二)部署说明

(1)    VSB9管理机

操作系统:CentOs6.4

IP:172.30.1.1

磁盘:/opt挂载435G

内存:8G

部署VSB高校版9.4.1

安装目录:/opt/vsb9

(2)    VSB9发布机1、2

操作系统:CentOs6.4

IP:172.30.1.2、172.30.1.3

磁盘:/opt挂载435G

内存:8G

部署VSB WEB 9.4.1

安装目录:/opt/vsb9mfp

Tomcat使用端口8084 Apache使用端口80

(3)    VSB9发布机3、4

操作系统:CentOs6.4

IP:172.30.1.4、172.30.1.5

磁盘:/opt挂载435G

内存:8G

部署VSB WEB 9.4.1

安装目录:/opt/vsb9mfp

Tomcat使用端口8084 Apache使用端口80

(4)    Oracle数据库服务器

操作系统:CentOs6.4

IP:172.30.0.2

磁盘:/opt挂载435G

内存:8G

部署oracle 11g

安装目录:/opt    

实例:webdb

注意:

1.172.30.1.3为异地备份服务器

2.在/etc/rc.d/rc.local中添加VSB自启动脚本。

3.在管理机放检测tomcat服务运行是否正常的脚本, 在发布机放检测apache服务运行是否正常的脚本。

(三)服务器及数据库管理账号密码

(1)    VSB9管理机

IP: 172.30.1.1

操作系统用户名密码:账号已交数字中心

启动服务命令: /opt/vsb9/bin/shutdown.sh

停止服务命令: /opt/vsb9/bin/startup.sh

监测tomcat脚本位置: /opt/vsb9/bin/vsb9tray.sh

链接web机:账号已交数字中心

站群登录地址:http://172.30.1.1/lg (http://vbsadmin.ctbu.edu.cn/lg) 账号已交数字中心

tomcat使用80端口,apache使用81端口

(2)    VSB9发布机1、2

IP: 172.30.1.2、172.30.1.3

操作系统用户名密码:账号已交数字中心

启动服务命令: /opt/vsb9/bin/shutdown.sh

停止服务命令: /opt/vsb9/bin/startup.sh

监测tomcat脚本位置: /opt/vsb9/bin/vsb9tray.sh

tomcat使用8084端口,apache使用80端口

(3)    VSB9发布机3、4

IP: 172.30.1.4、172.30.1.5

操作系统用户名密码:账号已交数字中心

启动服务命令: /opt/vsb9/bin/shutdown.sh

停止服务命令: /opt/vsb9/bin/startup.sh

监测tomcat脚本位置: /opt/vsb9/bin/vsb9tray.sh

tomcat使用8084端口,apache使用80端口

(4)    Oracle数据库服务器

IP: 172.30.0.2

数据库SID:webdb

数据库连接账号密码: 账号已交数字中心

dbf文件存放路径: /opt/oradata/

监测tomcat脚本位置: /opt/vsb9/bin/vsb9tray.sh

tomcat使用8084端口,apache使用80端口

(四)系统截图

(1)    登录入口

(2)    系统版本

(3)    软件环境

(4)    服务器参数

(5)    安全管理

(6)    备份恢复

(7)    网站管理

四、网站迁移及首页设计

(一)二级网站迁移

技术支持:潘蕊(西安博达软件有限公司)

迁移时间:2014-07-01—2014-10-15

完成情况:已完成二级网站的迁移工作任务

(1)    系统截图

(2)    迁移登记表

(二)学校主页设计及安排

设计时间:2014年10月01日至2014年10月20

完成情况:现已基本完成首页设计

演示地址:http://www2014.ctbu.edu.cn

设计截图:

五、与数字校园系统集成

(一)集成方案

(1)    CAS证书导入

 CAS证书

CAS服务器:211.83.206.94

CAS证书路径:/export/cart/casserver.cer

CAS包部署路径:/export/home/heer-app/cas

TOMCAT部署路径:/export/home/server/server_aq_dp

 CAS证书信任方法

以默认路径安装JDK1.6.0_25为例

在服务器上进行casserver.cer证书的jre信任

[root@zxx apache-tomcat]# /usr/java/jdk1.6.0_25/bin/keytool -import -v -alias casserver -file casserver.cer -keypass changeit -keystore /usr/java/jdk1.6.0_25/jre/lib/security/cacerts

输入keystore密码:  changeit

Owner: CN=www.test.com

发照者: CN=www.test.com

序号: 48853e41

有效期间: Tue Jul 22 09:56:17 CST 2008 至: Thu May 31 09:56:17 CST 2018

认证指纹:

        MD5  42:FC:AC:2D:9F:87:2E:F6:8E:B6:22:D5:3C:CB:03:89

        SHA1 9C:D1:53:BF:BD:25:9E:EF:14:75:2F:E1:FA:BF:B3:91:D3:E6:FE:48

信任这个认证? []  

认证已添加至keystore

[正在存储 /usr/java/jdk1.6.0_25/jre/lib/security/cacerts]

在服务器上进行casserver.cer证书的密钥(*.jks)信任

[root@zxx apache-tomcat]# /usr/java/jdk1.6.0_25/bin/keytool -import -v -alias casserver -file casserver.cer -keystore cas_tomcat.jks

输入keystore密码:  changeit

Owner: CN=www.test.com

发照者: CN=www.test.com

序号: 48853e41

有效期间: Tue Jul 22 09:56:17 CST 2008 至: Thu May 31 09:56:17 CST 2018

认证指纹:

        MD5  42:FC:AC:2D:9F:87:2E:F6:8E:B6:22:D5:3C:CB:03:89

        SHA1 9C:D1:53:BF:BD:25:9E:EF:14:75:2F:E1:FA:BF:B3:91:D3:E6:FE:48

信任这个认证? []  

认证已添加至keystore

[正在存储 cas_tomcat.jks]

(2)    CAS应用接口

CAS应用登入接口:https://ctbu-app.ctbu.edu.cn:8443/cas/login

CAS应用登出接口:https://ctbu-app.ctbu.edu.cn:8443/cas/logout

(二)集成过程

 

 

(1)、   JAVA系统SSO集成方式

 CAS简单登录的实现

      假设 CAS Server 单独部署在一台机器 A,而客户端应用部署在机器 B 上,由于客户端应用与 CAS Server 的通信采用 SSL,因此,需要在 A 与 B 的 JRE 之间建立信任关系。

按照cas证书导入方法,将 A 的证书添加到 B 的 trust store 中。如果多个客户端应用分别部署在不同机器上,那么每个机器都需要与 CAS Server 所在机器建立信任关系。

配置 CAS Filter

准备好应用 casTest1 和 casTest2 过后,分别部署在 B 和 C 机器上,由于 casTest1 和casTest2,B 和 C 完全等同,我们以 casTest1 在 B 机器上的配置做介绍,假设 A 和 B 的域名分别为 domainA 和 domainB。

从CAS服务器/export/home/heer-app/cas/WEB-INF/lib下载cas-client-core-3.1.1.jar 并拷贝到 casTest1/WEB-INF/lib目录下,修改 web.xml 文件,添加 CAS Filter,如清单  所示:

添加 CAS Filter

填写本地服务器,不需带http://

<param-value>domainB:8080</param-value>  不要带http://

<web-app>

 ...

 <filter>

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

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

   <init-param>

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

       <param-value>https://domainA:8443/cas/login</param-value>

   </init-param>

   <init-param>

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

       <param-value>https://domainA:8443/cas/serviceValidate</param-value>

   </init-param>

   <init-param>

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

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

   </init-param>

 </filter>

 <filter-mapping>

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

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

 </filter-mapping>

 ...

</web-app>

对于所有访问满足 casTest1/protected-pattern/ 路径的资源时,都要求到 CAS Server 登录,如果需要整个 casTest1 均受保护,可以将 url-pattern 指定为“/*”。

从以上配置可以看到,我们可以为 CASFilter 指定一些参数,并且有些是必须的,表格 1表格 2 中分别是必需和可选的参数:


表格 1. CASFilter 必需的参数

参数名

作用

edu.yale.its.tp.cas.client.filter.loginUrl

指定 CAS 提供登录页面的 URL

edu.yale.its.tp.cas.client.filter.validateUrl

指定 CAS 提供 service ticket proxy ticket 验证服务的 URL

edu.yale.its.tp.cas.client.filter.serverName

指定客户端的域名和端口,是指客户端应用所在机器而不是 CAS Server 所在机器,该参数或   serviceUrl 至少有一个必须指定

edu.yale.its.tp.cas.client.filter.serviceUrl

该参数指定过后将覆盖 serverName 参数,成为登录成功过后重定向的目的地址



表格 2. CASFilter 可选参数

参数名

作用

edu.yale.its.tp.cas.client.filter.proxyCallbackUrl  

用于当前应用需要作为其他服务的代理(proxy)时获取 Proxy Granting Ticket 的地址

edu.yale.its.tp.cas.client.filter.authorizedProxy  

用于允许当前应用从代理处获取 proxy tickets,该参数接受以空格分隔开的多个   proxy URLs,但实际使用只需要一个成功即可。当指定该参数过后,需要修改 validateUrl proxyValidate,而不再是 serviceValidate

edu.yale.its.tp.cas.client.filter.renew

如果指定为 true,那么受保护的资源每次被访问时均要求用户重新进行验证,而不管之前是否已经通过

edu.yale.its.tp.cas.client.filter.wrapRequest

如果指定为 true,那么 CASFilter 将重新包装   HttpRequest,并且使 getRemoteUser() 方法返回当前登录用户的用户名

edu.yale.its.tp.cas.client.filter.gateway

指定 gateway 属性

传递登录用户名

CAS 在登录成功过后,会给浏览器回传 Cookie,设置新的到的 Service Ticket。但客户端应用拥有各自的 Session,我们要怎么在各个应用中获取当前登录用户的用户名呢?CAS Client 的 Filter 已经做好了处理,在登录成功后,就可以直接从 Session 的属性中获取,如下所示:

在 Java 中通过 Session 获取登录用户名

                 

// 以下两者都可以

session.getAttribute(CASFilter.CAS_FILTER_USER);

session.getAttribute("edu.yale.its.tp.cas.client.filter.user");

通过 JSTL 获取登录用户名

                 

<c:out value="${sessionScope[CAS:'edu.yale.its.tp.cas.client.filter.user']}"/>

另外,CAS 提供了一个 CASFilterRequestWrapper 类,该类继承自HttpServletRequestWrapper,主要是重写了 getRemoteUser() 方法,只要在前面配置 CASFilter 的时候为其“ edu.yale.its.tp.cas.client.filter.wrapRequest ”参数为 true,就可以通过 getRemoteUser() 方法来获取登录用户名,具体方法如下所示:

通过 CASFilterRequestWrapper 获取登录用户名

                 

CASFilterRequestWrapper  reqWrapper=new   CASFilterRequestWrapper(request);

out.println("The logon user:" +   reqWrapper.getRemoteUser());

效果

在 casTest1 和 casTest2 中,都有一个简单 Servlet 作为欢迎页面 WelcomPage,且该页面必须登录过后才能访问,页面代码如下所示:


WelcomePage
页面代码

public class WelcomePage extends HttpServlet {

 public void doGet(HttpServletRequest   request, HttpServletResponse response)

 throws IOException, ServletException

 {

   response.setContentType("text/html");

   PrintWriter out =   response.getWriter();

     out.println("<html>");

     out.println("<head>");

     out.println("<title>Welcome to casTest2 sample   System!</title>");

     out.println("</head>");

     out.println("<body>");

   out.println("<h1>Welcome   to casTest1 sample System!</h1>");

     CASFilterRequestWrapper  reqWrapper=new   CASFilterRequestWrapper(request);

     out.println("<p>The logon user:" + reqWrapper.getRemoteUser()   + "</p>");

   HttpSession   session=request.getSession();

     out.println("<p>The logon user:" +

                    session.getAttribute(CASFilter.CAS_FILTER_USER)  +   "</p>");

     out.println("<p>The logon user:" +

          session.getAttribute("edu.yale.its.tp.cas.client.filter.user") +   "</p>");

   out.println("</body>");

     out.println("</html>");

   }

}

在上面所有配置结束过后,分别在 A, B, C上启动 cas, casTest1 和 casTest2,按照下面步骤来访问 casTest1 和 casTest2:

1.打开浏览器,访问 http://domainB:8080/casTest1/WelcomePage ,浏览器会弹出安全提示,接受后即转到 CAS 的登录页面

CAS 登录页面
CAS 登录页面

2.登录成功后,再重定向到 casTest1 的 WelcomePage 页面

登录后访问 casTest1 的效果
登录后访问 casTest1 的效果

可以看到图中地址栏里的地址多出了一个 ticket 参数,这就是 CAS 分配给当前应用的 ST(Service Ticket)

3.再在同一个浏览器的地址栏中输入 http://domainC:8080/casTest2/WelcomePage ,系统不再提示用户登录,而直接出现如下图 所示的页面,并且显示在 casTest1 中已经登录过的用户。

casTest1 中登录过后访问 casTest2 的效果
在 casTest1 中登录过后访问 casTest2 的效果

重新打开一个浏览器窗口,先输入

http://domainC:8080/casTest2/WelcomePage ,系统要求登录,在登录成功过后,正确显示 casTest2 的页面。之后再在地址栏重新输入 http://domainB:8080/casTest1/WelcomePage ,会直接显示 casTest1 的页面而无需再次登录。

 CAS登出

      在业务系统的logout模块中将logout链接的URL改成CAS服务器的logout接口即可。代码如下:

   Response.Redirect(“https://localhost:8443/cas/logout”);


 

(2)、   PHP系统SSO集成方式

 CAS单点登录测试环境搭建步骤

下载必要的软件:

CAS php客户端:CAS-1.0.1.tgz

搭建PHP运行环境

配置PHP-CAS客户端测试程序

解压CAS-1.0.1.tgz,将CAS 目录和CAS.php 拷入 C:\AppServ\www (AppServ默认安装目录中的www目录)中。这样, cas 的php客户端就配置好了。我们来测试一下这个php的cas 客户端是否起作用。

修改php客户端自带的一个示例:example_simple.php,并拷贝到www目录中。 

代码修改如下:

<?php

// phpCAS simple client

// import phpCAS lib

include_once('CAS.php');

phpCAS::setDebug();

// initialize phpCAS

phpCAS::client(CAS_VERSION_2_0,'localhost',8443,'cas');

// no SSL validation for the CAS server

phpCAS::setNoCasServerValidation();

// force CAS authentication

phpCAS::forceAuthentication();

// at this step, the user has been authenticated by the CAS server

// and the user's login name can be read with phpCAS::getUser().

// logout if desired

if (isset($_REQUEST['logout'])) {

        phpCAS::logout();

}

// for this test, simply print that the authentication was successfull

?>

<html>

 <head>

   <title>phpCAS simple client</title>

 </head>

 <body>

   <h1>Successfull Authentication!</h1>

   <p>the user's login is <b><?php echo phpCAS::getUser(); ?></b>.</p>

   <p>phpCAS version is <b><?php echo phpCAS::getVersion(); ?></b>.</p>

   <p><a href="?logout=">Logout</a></p>

 </body>

</html>

测试:

1)  访问http://localhost/ example_simple.php

2)  Cas检测到用户没有登录,转向:

https://localhost:8443/cas/login?service=http%3A%2F%2Flocalhost%2Fexample_simple.php 登录界面。

3)  在登录界面输入admin/admin 用户名和密码。

4)  登录成功,转回http://localhost/ example_simple.php,并显示有关信息。

 PHP-CAS客户端

PHP-CAS客户端主要CAS文件夹和CAS.php。   PHP实现cas简单认证步骤如下:

根据需要初始化不同的客户端

设置不是SSL的CAS认证

进行CAS认证

认证成功后点击登出完成登出。

cas-client的初始化

正如上面给出的example_simple.php的简单例子,利用代码“phpCAS::client(CAS_VERSION_2_0,'localhost',8443,'cas'); ”完成了client的初始化操作。

Cas-client的初始化是由CAS.php做数据检查,具体实现是由client.php来完成client类的构造。代码如下:

global $PHPCAS_CLIENT, $PHPCAS_INIT_CALL;

             

phpCAS::traceBegin();

if ( is_object($PHPCAS_CLIENT) ) {

      phpCAS::error($PHPCAS_INIT_CALL['method'].'() has already been called

(at '.$PHPCAS_INIT_CALL['file'].':'.$PHPCAS_INIT_CALL['line'].')');

      }

if ( gettype($server_version) != 'string' ) {

      phpCAS::error('type mismatched for parameter $server_version (should be `string\')');

}

if ( gettype($server_hostname) != 'string' ) {

      phpCAS::error('type mismatched for parameter $server_hostname (should be `string\')');

      }

if ( gettype($server_port) != 'integer' ) {

      phpCAS::error('type mismatched for parameter $server_port (should be `integer\')');

      }

if ( gettype($server_uri) != 'string' ) {

      phpCAS::error('type mismatched for parameter $server_uri (should be `string\')');

      }

// store where the initialzer is called from

$dbg = phpCAS::backtrace();

$PHPCAS_INIT_CALL = array('done' => TRUE,'file' => $dbg[0]['file'],'line' => $dbg[0]['line'],

                                         'method' => __CLASS__.'::'.__FUNCTION__);

……

CAS.php是一个phpCAS类,主要是为了CAS的实现做支持。可以在php代码中直接调用phpCAS类的方法,只要在代码前面加入“include_once('CAS.php');”。这个类中提供了两个initializationphpCAS client initializerphpCAS proxy initializer。分别初始化两种客户端:不带代理的客户端和有代理的客户端。该初始化都调用了client.php中的client的构造函数,根据传入的参数的不同来区分是否具体代理。代码如下:

//具有代理的client

$PHPCAS_CLIENT = new CASClient($server_version,TRUE/*proxy*/,

$server_hostname,$server_port,$server_uri,$start_session);

//不具有代理的client

$PHPCAS_CLIENT = new CASClient($server_version,FALSE/*proxy*/,

$server_hostname,$server_port,$server_uri,$start_session);

Client.php中的client构造主要完成以下工作:

存储以前的session,创建新session

判断是否有代理功能并判断当前server_version是否支持(CAS_VERSION_1_0不支持);

判断$server_hostname$server_port$server_uri是否合法;

如果上述都合法则修正$server_uri“/”“\”的区别);

判断是否有代理功能,有则设置是否是CallbackMode

如果是CallbackMode则判断phpCAS是否是https

获取并保存ticket并根据不同的版本把它从CGI中移除,为了安全。

设置不是SSLCAS认证

      调用phpCAS类中的setNoCasServerValidation()进行设置。设置该CAS服务认证不是SSL方式的认证。如果不加入这句语句的话认证可能无法正常运行。如下图4所示:

4:没有加入phpCAS::setNoCasServerValidation()语句

      输入帐户密码后画面会停留在图4这个页面,无论你点击“是”还是“否”都无法进入你想进入的系统。

      当加入phpCAS::setNoCasServerValidation()语句后,点击图4页面上的“是”则可以进入系统,如图5所示:

5:加入了phpCAS::setNoCasServerValidation()语句

 进行CAS认证

      PHP代码中加入phpCAS::forceAuthentication();即可进行CAS认证。

      forceAuthentication()方法是phpCAS类中的一个方法。它完成了CAS认证的检查,首先检测是否初始化$PHPCAS_CLIENT,成功之后再检查之前是否认证过,以及记录此次认证。代码如下:

function forceAuthentication()

{

      global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;

             

      phpCAS::traceBegin();

      if ( !is_object($PHPCAS_CLIENT) ) {

             phpCAS::error('this method should not be called before '.__CLASS__.'::client() or '.__CLASS__.'::proxy()');

      }

             

      $auth = $PHPCAS_CLIENT->forceAuthentication();

             

      // store where the authentication has been checked and the result

      $dbg = phpCAS::backtrace();

      $PHPCAS_AUTH_CHECK_CALL = array('done' => TRUE,'file' => $dbg[0]['file'],

'line' => $dbg[0]['line'],'method' => __CLASS__.'::'.__FUNCTION__,

'result' => $auth );

             

      if ( !$auth ) {

             phpCAS::trace('user is not authenticated, redirecting to the CAS server');

             $PHPCAS_CLIENT->forceAuthentication();

      } else {

             phpCAS::trace('no need to authenticate (user `'.phpCAS::getUser().'\' is already authenticated)');

      }

             

      phpCAS::traceEnd();

      return $auth;

}

认证的实现是在client.php中的forceAuthentication()方法完成,它来完成是否认证的检查以及进行认证。forceAuthentication()通过调用isAuthenticated()来检查之前是否登录过,如果没有登录过则重定向至CASisAuthenticated()则又调用wasPreviouslyAuthenticated()wasPreviouslyAuthenticated()在非代理模式下调用isSessionAuthenticated()来进行最终的session的检查从而完成是否认证的检查。

现在我们来看看这几个方法的具体工作是哪些。

isSessionAuthenticated()

function isSessionAuthenticated (){

return !empty($_SESSION['phpCAS']['user']);

}

从代码可以看出,isSessionAuthenticated ()只是对$_SESSION['phpCAS']['user']进行检查是否为空。如果为空的话则返回FALSE即没有认证过。反之返回TRUE即之前认证过了。

wasPreviouslyAuthenticated()

      wasPreviouslyAuthenticated()还区分了代理和非代理。

对于有代理的,则进行$_SESSION['phpCAS']['user']$_SESSION['phpCAS']['pgt']进行是否为空检查并进行UserPGTSTPT的赋值。不存在的都赋值为空。并用phpCAS::trace()进行记录信息。

对于没有代理的,则进行简单的phpCAS检查,调用isSessionAuthenticated ()来完成操作。同样调用phpCAS::trace()记录信息。并返回检查结果。

在代理模式只有当$_SESSION['phpCAS']['user']$_SESSION['phpCAS']['pgt']都存在的时候才返回TRUE,其他情况都返回FALSE。在非代理模式返回结构由isSessionAuthenticated ()产生。代码见附录2.

      备注:该方法还会检查是否是CallbackMode,并进行适当的赋值。

isAuthenticated()

      isAuthenticated()主要是在完成wasPreviouslyAuthenticated()检查返回TRUE的情况下对STPTPGT的检测(代理模式下才对PGT进行检测)。当存在ST时则对ST进行检测,调用validateST()完成检测,在检测成功的情况下记录信息返回TRUE,失败则返回FALSE。同样进行PTPGT检测。如果STPT都不存在则检测失败,返回FALSE

forceAuthentication()

      function forceAuthentication()

             {

             phpCAS::traceBegin();

             if ( $this->isAuthenticated() ) {

                    // the user is authenticated, nothing to be done.

                    phpCAS::trace('no need to authenticate');

                    $res = TRUE;

             } else {

                    // the user is not authenticated, redirect to the CAS server

                    if (isset($_SESSION['phpCAS']['auth_checked'])) {

                           unset($_SESSION['phpCAS']['auth_checked']);

                    }

                    $this->redirectToCas(FALSE/* no gateway */);

                    // never reached

                    $res = FALSE;

             }

             phpCAS::traceEnd($res);

             return $res;

             }

      forceAuthentication()并不复杂,它首先调用isAuthenticated()来检测是否登录过,在失败的情况下才进行重定向至CAS服务器,在此我就不多加解释了,代码一目了然。

      综上所述:CAS的认证步骤如下:

非代理模式(成功)

方法调用过程:

phpCAS::forceAuthentication()---->”PHPCAS_CLIENT->forceAuthentication()”----> “PHPCAS_CLIENT-> isAuthenticated()”---->” PHPCAS_CLIENT->wasPreviouslyAuthenticated()”

---->” PHPCAS_CLIENT->isSessionAuthenticated”

实际检测过程:

$_SESSION['phpCAS']['user']----> ST/PT---->TRUE

代理模式(成功)

方法调用过程:

phpCAS::forceAuthentication()---->”PHPCAS_CLIENT->forceAuthentication()”----> “PHPCAS_CLIENT-> isAuthenticated()”---->” PHPCAS_CLIENT->wasPreviouslyAuthenticated()”

实际检测过程:

$_SESSION['phpCAS']['user']&& $_SESSION['phpCAS']['pgt']---->ST/PTPGT---->TRUE

备注:

检测过程只要一个不通过就返回FALSE

检测结果是TRUE的无需登录直接进入业务系统。

检测失败尚未登录

FALSE---->” PHPCAS_CLIENT->redirectToCas()”---->CAS服务器进行认证

 登出

phpCAS::logout()

phpCAS::logout首先检测$PHPCAS_CLIENT是否被初始化,然后检测参数$params是否是array类型,如果是string类型则提示要求调用phpCAS::logoutWithUrl($url)。在检测$paramsarray类型后将$params中的$key = "service" $key = "url"的元素复制到$parsedParams中。并调用$PHPCAS_CLIENT->logout($parsedParams)进行logout处理。phpCAS::logout()的代码见附录4.

phpCAS中有很多中logout的方法,每种方法都能实现不同的登出方式,这些方法有:

logoutWithRedirectService($service)logoutWithRedirectServiceAndUrl($service, $url)

logoutWithUrl($url)还有上面说的最简单的logout()。他们的实现都很简单,都是先进行参数检测再调用$PHPCAS_CLIENT->logout(参数),根据输入不同的参数来完成不同的logout

$PHPCAS_CLIENT->logout($parsedParams)

      $PHPCAS_CLIENT->logout($parsedParams)完成logout功能,代码如下:

      function logout($params) {

             phpCAS::traceBegin();

             $cas_url = $this->getServerLogoutURL();

             $paramSeparator = '?';

             if (isset($params['url'])) {

                    $cas_url = $cas_url . $paramSeparator . "url=" . urlencode($params['url']);

                    $paramSeparator = '&';

             }

             if (isset($params['service'])) {

                    $cas_url = $cas_url . $paramSeparator . "service=" . urlencode($params['service']);

             }

             header('Location: '.$cas_url);

             session_unset();

             session_destroy();

             $this->printHTMLHeader($this->getString(CAS_STR_LOGOUT));

             printf('<p>'.$this->getString(CAS_STR_SHOULD_HAVE_BEEN_REDIRECTED).'</p>'

,$cas_url);

             $this->printHTMLFooter();

             phpCAS::traceExit();

             exit();

      }

      从代码可见,logout()根据传入参数的不同创建不同的cas_url从而logout到不同的页面。

      综上所述,要完成logout只用根据需求选择phpCAS中的不同logout方法即可完成。不同的logout方法归根结底都是通过调用CASClient类中的logout(参数),传入不同的参数来完成不同的登出。

(3)、   ASP.NET系统SSO集成方式

 CAS简单登陆实现

      http://www.ja-sig.org/downloads/cas-clients/dotnet/下载cas .net客户端,是一个dll文件,可以在asp.net项目中引用,然后通过下边的代码就可以使用:在web.config文件中增加关于cas服务器和本地服务的地址信息:

<configuration>      

      <appSettings>    

      <add key="casLoginURL" value="https://localhost:8443/cas/login" />    

      <add key="casValidateURL"value="https://localhost:8443/cas/serviceValidate"/>      

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

      </appSettings>

</configuration>

(备注:根据具体的服务地址进行设置。)

然后在Default.aspx页面功能代码中,使用下边的代码调用就可以了:

using DotNetCASClient;

protected void Page_Load(object sender, EventArgs e) {

      String userId = (String) Session["userId"];        

      if (userId == null) {

             DotNetCASClientServiceValidate client = new DotNetCASClientServiceValidate();

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

   }        

   Session["userId"] = userId;            

}

      如果直接使用客户端的话会报错误,如下图

      经过检查发现是在获取ticket后访问sso服务器的时候,无法获取反馈的xml信息。以下代码出错:XmlTextReader reader = new XmlTextReader(url);查询了,应该是在读取基于httpsurl的时候出错。所以直接使用提供的cas .net客户端dll不可以了,需要从https://www.ja-sig.org/svn/cas-clients/dotnet-client/trunk下载c#源代码,然后做一定的修改。

      DotNetCASClient.cscas .net客户端)中,增加:    

public class TrustAllCertificatePolicy : System.Net.ICertificatePolicy {

   public TrustAllCertificatePolicy() { }        

public bool CheckValidationResult(System.Net.ServicePoint sp,

System.Security.Cryptography.X509Certificates.X509Certificate cert,

System.Net.WebRequest req, int problem){            

   Console.WriteLine("Running Here!!!\n");            

   return true;        

   }    

}

      增加public class DotNetCASClientServiceValidate : LogCASExceptionspublic class DotNetCASClientProxyValidate: LogCASExceptionspublic String Authenticate(String ticket)中:

System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();

 CAS登出实现

      在从网上下载下来的的cas.net客户端代码没有登出这个功能,所以要实现这个功能我在客户端功能代码中加入语句让登出的URL指向CAS服务器的登出接口:https://localhost:8443/cas/logout即可。

      页面代码如下:

<asp:Button id="Button2" runat="server" Text="Logout" onclick="Button2_Click"></asp:Button>

      功能代码如下:

             protected void Button2_Click(object sender, System.EventArgs e)

       {

           Session. Abandon();

           Response.Redirect(“https://localhost:8443/cas/logout”);

       }

(4)、   ASP系统SSO集成方式

 CAS简单登录实现

根据CAS认证的流程以及对ASP.NET客户端的研究自己编写了ASP客户端。首先在需要通过CAS认证的页面的目录下创建一个叫casLogin.asp的文件,代码如下:

<%@ Language = Jscript%>

<%

//CAS服务器路径和业务服务器路径

var casLoginURL = "https://192.168.0.204:8443/cas/login" ;

var casValidateURL = "https://192.168.0.204:8443/cas/serviceValidate" ;

var serviceURL = "http://192.168.0.204:808/asp/test.asp";

userid = Session("userId");

if(userid ==null){

var ticket = Request.QueryString.Item("ticket").Item;

if(ticket == null){

//跳转至CAS服务器进行认证

Response.Redirect(casLoginURL + "?service=" + serviceURL);

}

//检查ticket是否有效

else{

var url = casValidateURL + "?ticket=" + ticket + "&service=" + serviceURL;

//Response.Redirect(url);

objXMLHTTP = Server.CreateObject("MSXML2.ServerXMLHTTP.4.0") ;

//不能删除这一行代码,否则会报错。

objXMLHTTP.setOption(2,13056);

objXMLHTTP.open("GET",url,false);

//objXMLHTTP.setRequestHeader("Content-Type", "text/xml");

//objXMLHTTP.setRequestHeader("charset", "UTF-8");

objXMLHTTP.send();

//Response.charSet ="UTF-8";

xmlText = objXMLHTTP.responseText;

objXMLHTTP = null;

xmldoc = Server.CreateObject("MSXML2.DOMDocument");

xmldoc.loadXML(xmlText);

root = xmldoc.documentElement;

//查找root中的标签是否包含"cas:authenticationSuccess"

succ = root.getElementsByTagName("cas:authenticationSuccess");

if(succ.length > 0){

//查找succ中的标签是否包含"cas:user"

userId = succ.item(0).getElementsByTagName("cas:user").item(0).text;

if(userId.length == 0)

Response.Redirect(casLoginURL + "?service=" + serviceURL);

}

else

Response.Redirect(casLoginURL + "?service=" + serviceURL);

}

Session("userId") = userId;

}

%>

然后在需要通过CAS认证的页面加入:<!--#include file="casLogin.asp"-->即可。这样输入该页面网址时,就会自动运行casLogin.asp文件从而跳转至CAS进行认证。

 CAS登出实现

CAS的登出很简单,只要创建一个logout.asp页面,页面代码如下:

<%@ Language = JScript%>

<%

//登出页面地址

var casLogoutURL = "https://192.168.0.204:8443/cas/logout" ;

//清空Session

Session.Abandon();

//跳转至登出页面

Response.Redirect(casLogoutURL);

%>

只要在需要登出的页面上加入以下代码:

<p><a href='logout.asp'>logout</a></p>

这样在页面上可以点击logout来完成登出。

(三)数据集成使用及效果

(1)、   数据集成

 建立中间表

create table shhty

(

      zgh varchar(20),//账号

      xm varchar(20) ,//姓名

      szbmmc varchar(100),//所在部门名称

      szbm varchar(20),//所在部门

      flag int //默认为1

)

create table shhty

(

      zgh varchar(20),

      xm varchar(200) ,

      szbmmc varchar(255),

      szbm varchar(100),

      flag int

)

create table middept

(

      bmh varchar(100),

      bmmc varchar(100),

      departmentid varchar(100),

      fbmh varchar(100),

      flag int

)

 静态登录组件代码

<%@ page contentType="text/html; charset=UTF-8"

%><%@ page import="webber.vsb.util.CertInfo"%>

<%@ page import="webber.vsb.util.CheckPassword"%>

<%@ page import="webber.vsb.util.HTMLUtil"%>

<%@ page import="webber.vsb.dao.WbsysuserDAO"%>

<%@ page import="webber.vsb.entity.Wbsysuser"%><jsp:useBean id="view" scope="page" class="webber.wbst.com.Container"

/><%@ page import="webber.wbst.com.*"

%><%@ page import="webber.core.GenerateUniqueId"

%><%@ page import="webber.vsb.sys.VsbResources"

%><%

   String [] props= {"应用标准组件", "furenqiang",  "2006/05/25", "webber", "1.0", "应用标准组件", Element.TPP_GENERAL,Element.PREVIEW_CONTENT_TYPE_ACTUAL};

   view.initial(pageContext, props, null);

   view.addLocaleMenuItem();

   view.setMenuGroup("userlogin","字体样式相关配置",Container.Default_Unfold);

   view.setMenuGroup("dltcxgpz","登陆退出按钮配置");

   view.addMenuItem("userlogin", "yhdlstyle", "style1", Container.CFG_FONT_STYLE, "用户登录字体样式");

   view.addMenuItem("userlogin", "yhmmstyle", "style1", Container.CFG_FONT_STYLE, "", "用户名称和密码字体样式");

   view.addMenuItem("userlogin", "yhzhstyle", "style1", Container.CFG_FONT_STYLE, "", "用户注册和取回密码字体样式");

   view.addMenuItem("userlogin", "startchar", "style2", Container.CFG_TEXT, "注册及取回密码前导符");

   view.addMenuItem("userlogin", "titleimg", "style2", Container.CFG_IMAGE_CHOOSE, "标题前导图");

   view.addMenuItem("userlogin", "titlelan", "style3", Container.CFG_TEXT, "用户名标签显示(默认为用户名)");

   

   view.addMenuItem("dltcxgpz", "submitimg", Container.CFG_IMAGE_CHOOSE, "登录按钮图片");

   view.addMenuItem("dltcxgpz", "exitimg", Container.CFG_IMAGE_CHOOSE, "退出按钮图片");

   view.doAction();

   

   String submitimgstr = "";

   if(view.image("submitimg") == null || view.image("submitimg").equals(""))

   {

       submitimgstr = "/system/resource/images/login/denglu_anniu_denglu.gif";

   }

   else

   {

       submitimgstr = view.image("submitimg");

   }

   

   String exitimgstr = "";

   if(view.image("exitimg") == null || view.image("exitimg").equals(""))

   {

       exitimgstr= "/system/resource/images/login/denglu_anniu_exit.gif";

   }

   else

   {

       exitimgstr= view.image("exitimg");

   }

   String titleimgsrc= "/system/resource/images/login/newlogin.gif";

   if(view.image("titleimg") != null && !view.image("titleimg").equals(""))

   {

       titleimgsrc=view.image("titleimg");

   }

   String formname = "a" + view.getUniqueId() + "a";

   

   String regnewurl = view.getTemplateLink("userregister", "会员注册页");

   String ret = "&retflag=1";

   regnewurl = regnewurl + "&wbstate=0" + ret;

   String updatepwurl = view.getTemplateLink("userregister", "会员注册页");

   updatepwurl = updatepwurl + "&wbstate=10" + ret;

   String getpwurl = view.getTemplateLink("userregister", "会员注册页");

   getpwurl = getpwurl + "&wbstate=20" + ret;

   Object obj = session.getAttribute("_username");

   if (obj != null)

   {

       String _userid = (String) session.getAttribute("_userid");

       Wbsysuser sysuser = WbsysuserDAO.getById(Integer.parseInt(_userid),view.getDbName());

       if(sysuser.getWbeditpass()==1&&view.getMode()!=1)

       {

           HTMLUtil.forwardPage(out,updatepwurl);

           return;  

       }

   }

   Object epobj = session.getAttribute("editpass");

   if(epobj!=null&&view.getMode()!=1)

   {

       HTMLUtil.forwardPage(out,updatepwurl);

       return;  

   }

%>

<%=view.includeJS(view.link("/system/dwr/engine.js"))%>

<%=view.includeJS(view.link("/system/dwr/util.js"))%>

<%=view.includeJS(view.link("/system/dwr/interface/WbmemberDWR.js"))%>

<%=view.includeJS(view.link("/system/dwr/interface/CheckPasswordDWR.js"))%>

<%=view.includeJS(view.link("/system/resource/js/login/reguser.js"))%>

<div id="logindiv<%=formname%>" style="text-align:center"></div>

<script>

var vc<%=formname%>="<%=formname%>";

function checkpassword(input)

{

   var instr = trim(input);

   if(instr == "")

       return false;

   return true;

}  

function statictlogin<%=formname%>()

{

    if(!newcheckinput())

   {

      return;

   }

   var account=document.getElementById("wbaccount");

   var password=document.getElementById("wbpassword");

   var logindiv = document.getElementById("logindiv<%=formname%>");

   logindiv.innerHTML="登录中.........";

   WbmemberDWR.userLogin("<%=view.getOwner()%>",account.value,password.value,vc<%=formname%>,function (data){staticloginresult<%=formname%>(data,password.value);});

}

function statictlogout<%=formname%>()

{

   WbmemberDWR.userLogout(loginresult<%=formname%>);

}

function staticloginresult<%=formname%>(data,pd)

{

   if(data.result=="true")

   {

//start

               CheckPasswordDWR.checkStaticSite(pd,function(data){

                   var result = data.split("@");

                   if(result[0]=="true")

                   {

                       window.location=window.location;

                   }else

                   {

                       //alert("登录成功!网站安全级别已升级,"+result[1]);

                       window.location='<%=updatepwurl%>';

                   }

               });

//end

   }else

   {

       alert(data.errcode);

       initlogin<%=formname%>();

   }

}

function loginresult<%=formname%>(data)

{

   if(data.result=="true")

   {

                   window.location=window.location;

   }else

   {

       alert(data.errcode);

       initlogin<%=formname%>();

   }

}

function initlogin<%=formname%>()

{

   

   WbmemberDWR.userIsLogin(vc<%=formname%>,'<%=view.getDbName()%>',buildlogin<%=formname%>);

}

function buildlogin<%=formname%>(data)

{

   var result="";

   if((data.isedit||data.wbeditpass)&&<%=view.getMode()!=1?"true":"false"%>)

   {

       window.location='<%=updatepwurl%>';

   }else{

   

   if(data.result=="true")

   {

       result+="<TABLE border=0 cellSpacing=0 cellPadding=0 width='<%=!"".equals(view.text("winwidth"))?view.text("winwidth"):"242"%>'><TR>";

       result+="<TD height=10 vAlign=top width=10><IMG src='/system/resource/images/login/zhuce_kuang_lefttopj.gif' width=14 height=10></TD>";

       result+="<TD background=/system/resource/images/login/zhuce_kuang_lefttopline.gif width='98%'></TD>";

       result+="<TD height=10 vAlign=top width=10><IMG src='/system/resource/images/login/zhuce_kuang_righttopj.gif' width=13 height=10></TD></TR>";

       result+="<TR><TD height=26 background=/system/resource/images/login/zhuce_kuang_leftline.gif></TD>";

       result+="<TD>";

       result+="<TABLE border=0 cellSpacing=0 cellPadding=2 width=242><TR>";

       result+="<TD width=3>&nbsp;</TD>";

       result+="<TD style='BORDER-BOTTOM: #cccccc 1px solid' <%=view.getStyle("yhmmstyle").replace("\"", "'")%> colSpan=3 noWrap><LABEL><%=view.getLocaleString("youarewelcome")%>,"+func<%=formname%>(data.name)+"</LABEL></TD>";

       result+="<TD style='BORDER-BOTTOM: #cccccc 1px solid' <%=view.getStyle("yhmmstyle").replace("\"", "'")%> width='20%' nowrap='nowrap'><%CertInfo cert = new CertInfo();if((cert.hasModule("all")||cert.hasModule("cas"))&&(VsbResources.getBoolean("login.allowopencaslink", false))){%><a href='/system/resource/cas/services/home.jsp?owner=<%=view.getOwner()%>' target='_blank'>单点登录管理</a><%}else{%>&nbsp;<%}%></TD>";

       result+="<TD width=3>&nbsp;</TD></TR>";

       result+="<TR><TD>&nbsp;</TD>";

       result+="<TD width='35%' noWrap><SPAN <%=view.getStyle("yhmmstyle").replace("\"", "'")%>><%=view.getLocaleString("thelastlogintime")%></SPAN></TD>";

       result+="<TD <%=view.getStyle("yhmmstyle").replace("\"", "'")%> colSpan=2><LABEL>"+data.enterdata+"</LABEL></TD>";

       result+="<TD rowSpan=2><LABEL><INPUT style='MARGIN-TOP: 3px; CURSOR: hand' onclick=statictlogout<%=formname%>(); value=<%=view.getLocaleString("logout")%> src='<%=exitimgstr%>' type=image name=logout> </LABEL></TD>";

       result+="<TD width=3>&nbsp;</TD></TR>";

       

       result+="<TR><TD>&nbsp;</TD>";

       if(data.entercount==0)

       {

           result+="<td colspan='3' <%=view.getStyle("yhmmstyle").replace("\"", "'")%>><%=view.getLocaleString("yourloginisthefirsttime")%></td>";

       }else

       {

           result+="<TD><SPAN <%=view.getStyle("yhmmstyle").replace("\"", "'")%>><%=view.getLocaleString("haslogin")%></SPAN></TD>";

           result+="<TD <%=view.getStyle("yhmmstyle").replace("\"", "'")%> colSpan=2><LABEL></LABEL>"+data.entercount+"<%=view.getLocaleString("frequency")%></TD>";

       }

       result+="<TD width=3>&nbsp;</TD></TR></TABLE></TD>";

       result+="<TD background=/system/resource/images/login/zhuce_kuang_rightline.gif></TD></TR>";

       result+="<TR><TD height=11 vAlign=bottom width=14><IMG src='/system/resource/images/login/zhuce_kuang_leftbottomj.gif' width=14 height=11></TD>";

       result+="<TD background=/system/resource/images/login/zhuce_kuang_bottomline.gif></TD>";

       result+="<TD height=11 vAlign=bottom width=13><IMG src='/system/resource/images/login/zhuce_kuang_rightbottomj.gif' width=13 height=11></TD></TR></TABLE>";            

   

   }else

   {

      /*

       result+="<TABLE border=0 cellSpacing=0 cellPadding=0 width='<%=!"".equals(view.text("winwidth"))?view.text("winwidth"):"242"%>'>";

       result+="<TR><TD height=10 vAlign=top width=10><IMG src='/system/resource/images/login/zhuce_kuang_lefttopj.gif' width=14 height=10></TD>";

       result+="<TD background=/system/resource/images/login/zhuce_kuang_lefttopline.gif width='98%'></TD>";

       result+="<TD height=10 vAlign=top width=10><IMG src='/system/resource/images/login/zhuce_kuang_righttopj.gif' width=13 height=10></TD></TR>";

       result+="<TR><TD height=26 background=/system/resource/images/login/zhuce_kuang_leftline.gif></TD>";

       result+="<TD><TABLE border=0 cellSpacing=0 cellPadding=2 width=242><TR><TD width=3>&nbsp;</TD>";

       result+="<TD style='BORDER-BOTTOM: #cccccc 1px solid' colSpan=3><LABEL><IMG src='<%=titleimgsrc%>'> <SPAN <%=view.getStyle("yhdlstyle").replace("\"", "'")%>><%=view.getLocaleString("wintitle")%></SPAN><SPAN style='color: #CCCCCC'>login</SPAN> </LABEL></TD>";

       result+="<TD style='BORDER-BOTTOM: #cccccc 1px solid' width='20%'>&nbsp;</TD>";

       result+="<TD width=6>&nbsp;</TD></TR>";

       

           

       result+="<TR><TD>&nbsp;</TD>";

       

       result+="<TD width='30%'><SPAN <%=view.getStyle("yhmmstyle").replace("\"", "'")%>><%=!"".equals(view.text("titlelan"))?view.text("titlelan").toString():view.getLocaleString("users")%></SPAN>:</TD>";

       result+="<TD colSpan=2><LABEL><INPUT style='BORDER-BOTTOM: #f3e9db 1px solid; BORDER-LEFT: #f3e9db 1px solid; WIDTH: 100px; HEIGHT: 20px; BORDER-TOP: #f3e9db 1px solid; BORDER-RIGHT: #f3e9db 1px solid'  maxLength=20 type=text name=wbaccount id=wbaccount tabindex=1> </LABEL></TD>";

       result+="<TD vAlign=center rowSpan=2><INPUT style='MARGIN-TOP: 3px; CURSOR: hand' onclick='statictlogin<%=formname%>()'  value=登录 src='<%=submitimgstr%>' type=image name=Submit tabindex=3> </TD>";

       

       result+="<TD width=6>&nbsp;</TD></TR>";

             

       result+="<TR><TD>&nbsp;</TD>";

       result+="<TD><SPAN <%=view.getStyle("yhmmstyle").replace("\"", "'")%>><%=view.getLocaleString("password")%></SPAN>:</TD>";

       result+="<TD colSpan=2><LABEL><INPUT style='BORDER-BOTTOM: #f3e9db 1px solid; BORDER-LEFT: #f3e9db 1px solid; WIDTH: 100px; HEIGHT: 20px; BORDER-TOP: #f3e9db 1px solid; BORDER-RIGHT: #f3e9db 1px solid'  value='' maxLength=15 type=password name=wbpassword id=wbpassword tabindex=2> </LABEL></TD>";

       result+="<TD width=6>&nbsp;</TD></TR>";

       

       

       result+="<TR>";

       result+="<TD height=5>&nbsp;</TD>";

       result+="<TD vAlign=absmiddle colSpan=2>";

       result+="<TABLE><TR>";

       result+="<TD vAlign=absmiddle><A href='<%=regnewurl%>'><SPAN <%=view.getStyle("yhzhstyle").replace("\"", "'")%>><%=!"".equals(view.getText("startchar"))?view.getText("startchar"):"&middot;"%></SPAN></A></TD>";

       result+="<TD><A href='<%=regnewurl%>' tabindex=4><SPAN <%=view.getStyle("yhzhstyle").replace("\"", "'")%>><%=view.getLocaleString("newusers")%></SPAN></A></TD></TR></TABLE></TD>";

       result+="<TD vAlign=center colSpan=2>";

       result+="<TABLE><TR>";

       result+="<TD vAlign=absmiddle><A href='<%=getpwurl%>'><SPAN <%=view.getStyle("yhzhstyle").replace("\"", "'")%>><%=!"".equals(view.getText("startchar"))?view.getText("startchar"):"&middot;"%></SPAN></A></TD>";

       result+="<TD><A href='<%=getpwurl%>' tabindex=5><SPAN <%=view.getStyle("yhzhstyle").replace("\"", "'")%>><%=view.getLocaleString("forgetpass")%></SPAN></A></TD></TR></TABLE></TD>";

       result+="<TD width=6>&nbsp;</TD></TR></TABLE></TD>";

       result+="<TD background=/system/resource/images/login/zhuce_kuang_rightline.gif></TD></TR>";

       result+="<TR><TD height=11 vAlign=bottom width=14><IMG src='/system/resource/images/login/zhuce_kuang_leftbottomj.gif' width=14 height=11></TD>";

       result+="<TD background=/system/resource/images/login/zhuce_kuang_bottomline.gif></TD>";

       result+="<TD height=11 vAlign=bottom width=13><IMG src='/system/resource/images/login/zhuce_kuang_rightbottomj.gif' width=13 height=11></TD></TR>";

     

       result+="</table>";

       */

       result+="<TABLE border=0 cellSpacing=0 cellPadding=0 width='<%=!"".equals(view.text("winwidth"))?view.text("winwidth"):"242"%>'>";

       result+="<tr><td><A href='/system/resource/code/auth/caslogin.jsp'>认证登陆</a></td></tr>";

       result+="</table>";

   }

   var logindiv = document.getElementById("logindiv<%=formname%>");

   logindiv.innerHTML=result;

   }

}

function func<%=formname%>(str)

{

   var reg = /<|>/g;

   str = str.replace(reg,function($1){

       if($1=='<'){

           return '&lt;';

       }else{

           return '&gt;';

       }

   });

   return str;

}

initlogin<%=formname%>();

</script>

 登陆组件样式配置

<script language='JavaScript' src='${v_link("/system/resource/js/login/reguser.js")}'></script>

 <script>

 function checkpassword(input)

  {

           var instr = trim(input);

           if(instr == "") return false;

                return true;

  }

</script>

<#if isLogin><#--登陆用户存在的操作代码-->

<table width="100%">

<tr align="center">

<td width="30%"> <span style="font-size: 12px; color: #333333;">昵称:${nickName} </td>

<td width="40%"> <span style="font-size: 12px; color: #333333;"><#if enterCount=='0'>上次登录时间:${lastEnterDate}</#if>

<#if enterCount!='0'>最后登录时间:${lastEnterDate}</#if> </td> <td width="20%"> <span style="font-size: 12px; color: #333333;">

<#if enterCount=='0'>您是首次登录!</#if><#if enterCount!='0'>你是第${enterCount}次登录!</#if> </td>

<td width="47" align="left">

<input STYLE='margin-bottom: 2px' type='image' src='/system/resource/images/login/anniu_exit_small.gif' style='cursor:pointer' name='blogout' value='退出' onclick='logout${UUID}()'> </td>

</tr>

 </table> <#else> <#--登录用户不存在的操作代码-->

 <A href="/system/resource/code/auth/caslogin.jsp">认证登陆</a>

<form name="${formName}" method="post" style="display: inline"> ${hidden}

  <table style="display: none;"> <tr>

  <td valign="middle"> <span style="font-size: 12px; color: #333333;">用户∶</span> <input name='${userTextName}' id='${userTextName}' type='text' style="border: 1px solid #CCCCCC; font-size: 12px" tabindex='1' size='12' maxlength='20' /> <span style="font-size: 12px; color: #333333;">&nbsp;密码∶</span> <input name='${pswTextName}' id='${pswTextName}' type='password' style="border: 1px solid #CCCCCC; font-size: 12px" tabindex='2' size='12' maxlength='15' />

  <input tabindex="3" type="image" src="/system/resource/images/login/rukou_anniu_denglu.gif" STYLE="margin-bottom: 2px; cursor: hand; FONT-SIZE: 12px; FILTER: progid : DXImageTransform . Microsoft . Gradient(GradientType = 0, StartColorStr = #ffffff, EndColorStr = #cecfde); CURSOR: hand; COLOR: #666666; font-weight: bold; background-color: #FFFFFF; padding: 1px; border: 1px solid #d7d7d7; vertical-align: middle; text-align: center; background-image: url(/system/resource/images/login/rukou_anniu_denglu.gif);" onClick="if(!checkinput('${formName}')) return false;"> &nbsp;&nbsp; <a href="${regURL}" style="COLOR: #000000; text-decoration: none;"> <span style="font-size: 12px; color: #666666;">&middot;</span> <span style="font-size: 12px; color: #666666;"> 新用户注册</span>

   </a> <a href='${getpwURL}' style="COLOR: #000000; text-decoration: none;"> <span style="font-size: 12px; color: #666666;">&middot;</span>

   <span style="font-size: 12px; color: #666666;"> 取回密码</span> </a> </td> </tr>

   </table>

</form>

</#if>

 登陆组件代码

<%@ page contentType="text/html; charset=UTF-8"

%><%@ page import="webber.core.GenerateUniqueId"

%><%@ page import="webber.wbst.com.*"

%><%@ page import="webber.wbst.com.token.Token "

%><%@ page import="webber.vsb.util.MultisiteLoginMange"

%>

<%@ page import="webber.vsb.util.CertInfo"%>

<%@ page import="webber.core.StringUtil"%>

<%@ page import="webber.vsb.util.CheckPassword"%>

<%@ page import="webber.vsb.util.HTMLUtil"%>

<%@ page import="webber.vsb.dao.WbsysuserDAO"%>

<%@ page import="webber.vsb.entity.Wbsysuser"%><jsp:useBean id="view" scope="page" class="webber.wbst.com.Container"

/><jsp:useBean id="userpage" scope="page" class="webber.wbst.com.UserPage"

/>

<%

   String [] keys1 =

   {

       "不刷新",

       "刷新"

   };

   String [] values1 =

   {

       "no",

       "yes"

   };

   String [] props =

   {

       "带注册的用户登录入口",

       "gewei",

       "2010/5/4",

       "webber",

       "1.0",

       "带注册的用户登录入口",

       Element.TPP_INTERACT

   }; //layout 定义

   String [] fields =

   {

       "wboperation",

       "wbstate",

       "returnurl",

       "wbaccount",

       "wbpassword",

       "wbname",

       "wbsex",

       "wbidcard",

       "wbbirthday",

       "wbaddress",

       "wbemail",

       "wbhomepage",

       "wbcall",

       "wbphone",

       "wbdegree",

       "wbwork",

       "wbregisterdate",

       "wbenterdate",

       "wbentercount",

       "wbquestion",

       "wbanswer",

       "wbmemo",

       "errornotice",

       "errorpw",

       "errorca",

       "erroric",

       "errorem"

   }; //必须获得的 action 输出的参数

   view.initial(pageContext, props, fields);

   view.addTplMenuItem();

   view.setMenuGroup("firstnews", "登录后刷新本页面配置", Container.Default_Unfold);

   view.addMenuItem("firstnews", "isloadpage", Container.CFG_SELECT, "登录后是否刷新本页面", keys1, values1);

   view.doAction();

   

    String UUID =view.getUniqueId();

   //获取新用户注册的url

   String regURL = view.getTemplateLink("userregister", "会员注册页");

   String ret = "&retflag=1";

   regURL = regURL + "&wbstate=0" + ret;

   view.setTemplateValue("regURL", regURL);

   

   //获取取回密码的url

   String updatepwurl = view.getTemplateLink("userregister", "会员注册页");

   updatepwurl = updatepwurl + "&wbstate=10" + ret;

   String getpwURL = view.getTemplateLink("userregister", "会员注册页");

   getpwURL = getpwURL + "&wbstate=20" + ret;

   view.setTemplateValue("getpwURL", getpwURL);

   

   Object objname = session.getAttribute("_username");

   if (objname != null)

   {

       String _userid = (String) session.getAttribute("_userid");

       Wbsysuser sysuser = WbsysuserDAO.getById(Integer.parseInt(_userid),view.getDbName());

       if(sysuser.getWbeditpass()==1&&view.getMode()!=1)

       {

           HTMLUtil.forwardPage(out,updatepwurl);

           return;  

       }

   }    

   Object epobj = session.getAttribute("editpass");

   if(epobj!=null&&view.getMode()!=1&&"true".equals(epobj.toString()))

   {

       HTMLUtil.forwardPage(out,updatepwurl);

       return;  

   }

   

   

   String uid = request.getRemoteUser();

   String uid2 = (String)session.getAttribute("uid");

   if(null!=uid2)

       uid= uid2;

       

   String owner = view.getOwner();

   //获取用户名

   String account = StringUtil.getParameter(request,"wbaccount","");

   //获取密码

   String password = StringUtil.getParameter(request,"wbpassword","");

   //判断用户名是否为空或null

   //登录验证

   //获取登陆action

   String  action = StringUtil.getParameter(request,"haction","");

   

   out.print("<script lanauage='javascript'>function logout"+

   UUID+"(){flogout"+UUID+".haction.value = 'logout';flogout"+

   UUID+".submit();}</script><form name='flogout"+

   UUID+"'style='display: none'><input type='hidden' name='haction'><input type='hidden' name='wbtreeid' value='"+view.getColumnId()+"'></form>");    

   if(action!=null && action.equals("logout"))

   {

           userpage.logout(session);

           out.println(MultisiteLoginMange.getLogOutUserJavaScript(request,response));

            if(uid!=null)

           {

             HTMLUtil.forwardPage(out,"/system/resource/caslogout.jsp");

         

             }

           %>

           <script language = "JavaScript">

               flogout<%=UUID%>.haction.value = "";

               flogout<%=UUID%>.submit();

           </script>

<%    }  

     

   boolean bl = false;    

   if(!(account==null) && (!account.equals(""))&& Token.isValidateToken(request))

   {                  

     userpage.init(request, response, owner);

       //判断是否登陆

       bl = userpage.login(account, password);

       //获取错误信息

       String errMessage = userpage.getErrMessage();

       if(!bl)

       {

           out.print("<script language = 'JavaScript'>alert('"+errMessage+"');</script>");

           response.sendRedirect("tplreg02.jsp");

       }

       else

       {

           Object name = session.getAttribute("_username");

           if (name != null)

           {

               String _userid = (String) session.getAttribute("_userid");

               Wbsysuser sysuser = WbsysuserDAO.getById(Integer.parseInt(_userid),view.getDbName());

               if(sysuser.getWbeditpass()==1&&view.getMode()!=1)

               {

                   HTMLUtil.forwardPage(out,updatepwurl);

                   return;  

               }

           }                    

           //验证密码是否在允许范围内

           if(password!=null&&!"".equals(password))

           {

             CheckPassword cp = new CheckPassword();

             boolean sign = cp.checkSite(password);

             if(!sign)

             {

                 session.setAttribute("editpass","true");

                 if(view.getMode()!=1)

                 {

                     HTMLUtil.forwardPage(out,updatepwurl);

                     return;

                 }

             }

           }  

           out.println(MultisiteLoginMange.getLoginUserJavaScript(request,response,account));

           if(view.getRadio("isloadpage","no").equals("yes"))

           {

%>

               <script language = "JavaScript">

                   window.location=window.location;

               </script>              

<%

           }  

       }

   }

       boolean b2 = false;

   if(null!=uid&&(!uid.equals(""))){

       account = uid;

       password = "webberchen123";

       userpage.init(request, response, owner);

       //判断是否登陆

       b2 = userpage.login(account, password);

       //获取错误信息

       String errMessage1 = userpage.getErrMessage();

       if(!b2)

       {

           out.print("<script language = 'JavaScript'>alert('11"+errMessage1+"22"+account+"');</script>");

           response.sendRedirect("tplreg02.jsp");

       }

       else

       {

           Object name1 = session.getAttribute("_username");

           if (name1 != null)

           {

               String _userid1 = (String) session.getAttribute("_userid");

               Wbsysuser sysuser = WbsysuserDAO.getById(Integer.parseInt(_userid1),view.getDbName());

               if(sysuser.getWbeditpass()==1&&view.getMode()!=1)

               {

                   HTMLUtil.forwardPage(out,updatepwurl);

                   return;  

               }

           }                    

           out.println(MultisiteLoginMange.getLoginUserJavaScript(request,response,account));

           if(view.getRadio("isloadpage","no").equals("yes"))

           {

%>

               <script language = "JavaScript">

                   window.location=window.location;

               </script>              

<%

            }  

     }

       

   }

   String hidden =" <input type='hidden' name='TOKENKEY' value='"+Token.createToken(request)+"'><input type='hidden' name='wbtreeid' value='"+view.getColumnId()+"'>";

   view.setTemplateValue("hidden", hidden);

   //UUID 唯一标识

      view.setTemplateValue("UUID", UUID);

   session.setAttribute("UUID",UUID);

   

   //form名称唯一标识

    String formName ="a"+UUID;

   view.setTemplateValue("formName", formName);

   //获取用户名

   Object obj = session.getAttribute("_useraccount");

   boolean isLogin =obj==null?false:true;

   //用户是否登录状态  

   view.setTemplateValue("isLogin", new Boolean(isLogin));

   //是否显示单点登录

   CertInfo cert = new CertInfo();

   if(cert.hasModule("all")||cert.hasModule("cas"))

   {

       view.setTemplateValue("caslogLink","/system/resource/cas/services/home.jsp?owner="+view.getOwner());

   }

   //存在的情况

   //用户的昵称

   String nickName = session.getAttribute("_username")==null?"":(String)session.getAttribute("_username");  

   view.setTemplateValue("nickName", StringUtil.escapeHTMLTags(nickName));

   

   //获取最后一次登陆的时间

   String lastEnterDate =session.getAttribute("_username")==null?"":(String)session.getAttribute("_userlastenterdate");

   view.setTemplateValue("lastEnterDate", lastEnterDate);

   

   //获取输入的次数

   String ecount = (String)session.getAttribute("_entercount");

   String enterCount= session.getAttribute("_entercount")==null?"0":(String)session.getAttribute("_entercount");  

   view.setTemplateValue("enterCount",enterCount);

   //密码最大长度

 view.setTemplateValue("passlen_max",Integer.valueOf(CheckPassword.site_max));

   //密码最小长度

 view.setTemplateValue("passlen_min",Integer.valueOf(CheckPassword.site_min));      

   //用户名文本框名称

   view.setTemplateValue("userTextName","wbaccount");

   //密码文本框名称

   view.setTemplateValue("pswTextName", "wbpassword");

         

   view.showTemplate();

%>

 用户数据集成使用

因我校用户只为数字加字母,需修改 system/sys/user/sysuser.jsp 文件对帐户必为字母的限制。

----------取消会员字母限制---------

 if(document.all.username.value == "")

           {

               alert("请输入帐号");

               document.all.username.focus();

               return false;

           }

           else

           {

               var re = /^[a-z][a-z0-9_]*$/; 改为  var re = /^[a-z0-9_]*$/;

----------end

(2)、   使用方式

 复制已经修改好的前台的web.xml

(例如:D:\VSB9\owners\ms\ROOT\WEB-INF\web.xml

分别到D:\VSB9\owners\站点名称\ROOT\WEB-INF目录

替换掉原本的web.xml

 快速发布整个页面

 重启服务

(3)、   使用效果

 发布对内文章

设置访问权限

查看时,对内信息会自动进行统一认证,认证通过,才可查看内容。

 
       
 
版权所有 www.dc2277.com,澳门网上娱乐 渝ICP备09000381号 校长信箱
华岩校区地址:重庆市九龙坡区九龙科技园华龙大道1号 邮编:400052 电话:023-68613575
合川校区地址:重庆市合川区高校园区思源路15号 邮编:401520 电话:023-42860045