miketwais

work up

CAS单点登录整合JAVA和PHP系统配置方法及思路

最近做一个java项目和php项目的单点集成。选择用一个成熟的方案:耶鲁大学的CAS方案,这个方案也是大众普遍采用的一种方法,开源。
做之前首先要普及一下做“单点登录”的思路,要不也是瞎子摸象。
和所谓单点?就是要在一个平台(网页页面)上完成登录工作。那么一次登录工作中包含哪些步骤?
1.用户名密码验证。
2.用户授权信息,包括设置session,cookie等。

那么问题就来了,本来独立的系统都有自己的登陆流程和方法,现在要做一次“单点登录集成”,我们就需要改动子系统的登陆流程来适应单点登录。那么怎么改动呢?要知道怎么改动首先得了解CAS方案,在CAS开源项目中有CAS服务端和CAS客户端。
顾名思义服务端就是接受请求处理请求的,用来实现统一验证。那么客户端就是用来和我们的子系统进行集成的一些工具。关于CAS先介绍这么多。最后来张网上的时序图:

下面介绍下标准的配置过程(网上教程多,但都有点问题,下面版本亲测可行)


一.配置CAS服务端
下载:http://downloads.jasig.org/cas/ 选择cas-server-3.4.4-release.zip
解压cas-server-3.4.4-release.zip将modules目录下的cas-server-webapp-3.4.4.war改名称为cas.war复制到tomcat的webapps下,启动tomcat,访问:http://localhost:8080/cas/login 就可以看到登录界面了

cas服务端默认采用的是 用户名=密码的验证,并且采用的是https验证,需要给tomact配置证书,本系统没有采用https验证。
不采用https验证,服务器端需要配置
1、cas\WEB-INF\deployerConfigContext.xml
<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
p:httpClient-ref="httpClient"/>

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

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

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

服务器端退出访问:http://localhost:8080/cas/logout
登出页面:


到这里已经能看到简单的登入登出效果了,但是一般系统的认证都是要链接数据库的,下面来配置下数据库相应的设置。
更改服务器端验证方式,采用数据库验证:
1.修改配置文件deployerConfigContext.xml,加jdbc连接池:(以mysql为例)
<bean id="mysqlDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/webwork" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
2. 配置加密方式,cas内置的有MD5加密,也可以写自己的加密类,实现org.jasig.cas.authentication.handler.PasswordEncoder接口即可:
<bean id="passwordEncoder"
class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder" autowire="byName">
<constructor-arg index="0" value="MD5"/>
</bean>
3. 注释掉默认的验证方式,采用数据库查询验证:
<property name="authenticationHandlers">
<list>
<!----注释掉这里的默认验证方式,采用以下验证QueryDatabaseAuthenticationHandler-->
<!--
<bean
class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" /> -->
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
<property name="dataSource" ref="mysqlDataSource" />
<property name="sql" value="select user_password from pub_user where user_name = ?" />
<property name="passwordEncoder" ref="MD5PasswordEncoder"/>
</bean>
</list>
</property>

 

二.配置java客户端。
下载客户端程序:http://downloads.jasig.org/cas-clients/ 选择cas-client-3.2.0版本
将modules下的jar复制到java客户端Casclient1的lib下,在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-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 该过滤器负责用户的认证工作,必须启用它 -->
<filter>
<filter-name>CASFilter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>http://localhost:8080/cas/login</param-value>
<!--这里的server是服务端的IP-->
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://localhost:8080</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CASFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 该过滤器负责对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>http://localhost:8080/cas</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://localhost:8080</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!--
该过滤器负责实现HttpServletRequest请求的包裹,
比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。
-->
<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>
org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<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 Assertion Thread Local Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

到这里服务端和客户端的配置已经结束,接下来就需要来修改客户端的登陆流程,注意:需要对原系统的登陆流程做修改!!

下面给一个DEMO:
<%
AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal();
String username = principal.getName();
Map attributes = principal.getAttributes();
String user_id = Conver.convertNull(attributes .get("user_id"));
//下面就要根据user_id来获取相应的权限信息了(赋权)
//最后将用户信息和权限信息塞入到session中
session.setAttribute("user",user);
session.setAttribute("list_authority_menu", list_authority_menu);
%>
<br/>----------------------------------------------------------<br/>
<h1>登录成功,这是客户端1啊</h1><br/>
用户名:<%=username %><br/>
<a href="http://localhost:8080/cms">进入客户端2</a><br/>
<a href="http://localhost:8080/cas/logout?service=http://localhost:8989/webwork">退出</a><br/>
现在达到的效果:
访问localhost:8080/webwork的时候会跳转到CAS登录页面,登录成功后成功转向localhost:8080/webwork的登录成功页面,这时访问另一个系统cms时发现不需要登录即显示登录成功页面,java单点登录成功。

三.集成php语言的系统
下载php CAS客户端 http://downloads.jasig.org/cas-clients/php/ 我们选择:CAS-1.2.0RC2版本
将CAS文件夹和CAS.php复制到工程中,修改CAS/client.php,将其中的https改为http,将docs/examples/example_simple.php复制到工程中,修改如下:
<?php
// import phpCAS lib
include_once('CAS.php');
phpCAS::setDebug();
// initialize phpCAS
phpCAS::client(CAS_VERSION_2_0,'127.0.0.1',8080,'cas');
// no SSL validation for the CAS server
phpCAS::setNoCasServerValidation();
// force CAS authentication
phpCAS::handleLogoutRequests(); 这里会检测服务器端java退出的通知,就能实现php和java间同步登出了。
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'])) {

$param=array("service"=>"http://localhost/cms/example_simple.php");//退出登录后返回
phpCAS::logout($param);

}
// for this test, simply print that the authentication was successfull
?>
<html>
<head>
<title>phpCAS simple client</title>
</head>
<body>
<h1>Successfull Authentication!这是客户端1</h1>
<p>the user's login is <b><?php echo phpCAS::getUser(); ?></b>.</p>
//下面需要利用获取的用户信息user_id等去获取该用户的用户信息及授权信息,并设置到session和cookie完成php端的登陆(主要工作量在这里!)
<p>phpCAS version is <b><?php echo phpCAS::getVersion(); ?></b>.</p>
<p><a href="http://192.168.18.8:8989/webwork">去java客户端1</a></p>
<p><a href="?logout=">退出</a></p>
</body>
</html>
注意:php配置需要开启php_curl

就这么多了,直接把配置打包上传了。

JAVA项目下的WEB-INF/web.xml

CAS服务端下载(只包含了cas下面的WEB-INF文件夹下的)lib和class文件夹中文件太大,上传不了,也不影响。

 特别提示:若php项目是SESSION会话机制,则cas端退出,可以同时登出php端,但是一般php web项目都是cookie会话保持,所以这里会出现一种状况:casJava端退出了,但是php web端并没有退出,这里是个坑,需要根据自己情况处理。

posted @ 2016-08-11 15:08  MasonZhang  阅读(892)  评论(0)    收藏  举报