SSO单点登录之CAS-Server
Prerequisites
CAS Server 3.5.x.,下文以$CAS-SERVER表示。CAS Client 3.3.x.,下文以$CAS-CLIENT表示。Tomcat 7.x,下文以$CAS_TOMCAT_HOME表示。GateIn-3.8.1.Final-tomcat-7,下文以$GATEIN_HOME表示。
最近公司需要对之前的多个Web应用系统进行整合,希望用户在登录某个应用系统时,能直接访问其他的Web应用系统,且不需要再次登录。既我们经常说的单点登录,最后,我选择了
CAS,并将其整合进了GateIn portal。接下来,将整理一下原理和整合步骤。
所有项目代码示例可在github上下载。
CAS介绍
CAS(Central Authentication Service)是Yale大学发起的一个开源项目,旨在为Web应用系统提供一种可靠的单点登录。单点登录,既在多个应用系统中,用户只需登录一次就可以访问所有相互信任的应用系统。CAS Client支持非常多的客户端,包括JAVA、PHP、Ruby等。
接下来,接介绍一下CAS系统。
CAS 系统组成
CAS系统架构由两部分组成,CAS Server、CAS Clients,两者可以通过多种协议进行通信。
CAS Server
CAS Server是一个构建在Spring Framework上的Java servlet,通过分配和诊断tickets,负责认证用户以及授权。
CAS Clients
CAS Clients负责对用户的认证工作,CAS Clients负责处理对客户端受保护资源的访问请求,需要登录时,重定向到CAS Server。
CAS Clients与受保护的客户端应用部署在一起,以Filter方式保护受保护的资源。
CAS协议流程
CAS协议流程如下图所示,展示了用户同时访问多个应用系统的流程。多个应用系统能实现单点登录的基本流程为,当用户首次访问需要登录才能访问的页面时,会自动重定向到CAS Server的登陆页面,成功认证完后,会在CAS Server的域中设置CASTGC的Cookie,最终登陆完成后,服务器会创建一个session会话,用于之后与应用系统的交互。当用户同时再登陆另外一个应用系统时,同样会跟之前一样,重定向到CAS Server的登陆页面,区别是此时已经有了CAS Server域中的CASTGC,重定向时会附带该Cookie,CAS Server验证之后返回一个ticket,之后浏览器重新请求原访问页面,并附带ticket参数,CAS Server诊断有效后,返回原应用系统的重定向,且设置该域的session Cookie,浏览器最后请求原页面,并附带session Cookei,应用系统诊断后返回请求内容。
需要注意的是,当成功登陆完某个系统后,如果继续再访问该系统的其他资源页面,是不需要再次与CAS Server进行交互的,应用系统将根据session直接进行诊断。

GateIn Portal集成CAS Server
部署CAS
- 打开
$CAS_TOMCAT_HOME/webapps/$CAS-SERVER/WEB-INF/deployerConfigContext.xml,替换:为如下:1
<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
如上所示,用来配置1
2
3
4
5
6
7<bean class="org.gatein.sso.cas.plugin.AuthenticationPlugin">
<property name="gateInProtocol"><value>http</value></property>
<property name="gateInHost"><value>localhost</value></property>
<property name="gateInPort"><value>8080</value></property>
<property name="gateInContext"><value>portal</value></property>
<property name="httpMethod"><value>POST</value></property>
</bean>GateIn Portal的服务地址。 - 下载
GateIn SSO package,下载地址,解压后,将其cas/plugin/WEB-INF/lib下的jar包拷贝到$CAS_TOMCAT_HOME/webapps/$CAS-SERVER/WEB-INF/lib目录。 - 默认,登出用户时
CAS Server会展示一个CAS提供的登出页面,然后跳转回Portal页,如果想要保留原有Portal的登出,打开$CAS_TOMCAT_HOME/webapps/$CAS-SERVER/WEB-INF/cas-servlet.xml,添加followServiceRedirects="true"参数:1
2
3
4
5
6<bean id="logoutController" class="org.jasig.cas.web.LogoutController"
p:centralAuthenticationService-ref="centralAuthenticationService"
p:logoutView="casLogoutView"
p:warnCookieGenerator-ref="warnCookieGenerator"
p:ticketGrantingTicketCookieGenerator-ref="ticketGrantingTicketCookieGenerator"
p:followServiceRedirects="true"/>
部署GateIn Portal
为了能让
Portal使用CAS Server提供的单点登陆系统,首先配置Portal的SSO参数,在$GATEIN_HOME/gatein/conf/configuration.properties文件中,修改和添加如下内容:1
2
3
4
5
6
7
8
9gatein.sso.enabled=true
gatein.sso.callback.enabled=${gatein.sso.enabled}
gatein.sso.login.module.enabled=${gatein.sso.enabled}
gatein.sso.login.module.class=org.gatein.sso.agent.login.SSOLoginModule
gatein.sso.server.url=http://localhost:8086/cas-server
gatein.sso.portal.url=http://localhost:8080
gatein.sso.filter.logout.class=org.gatein.sso.agent.filter.CASLogoutFilter
gatein.sso.filter.logout.url=${gatein.sso.server.url}/logout
gatein.sso.filter.login.sso.url=${gatein.sso.server.url}/login?service=${gatein.sso.portal.url}/@@portal.container.name@@/initiatessologin如上,为配置
CAS Server的服务器信息等。如果需要改变账户系统的存储方式, 比如改为
MySQL数据库,还需要在$GATEIN_HOME/gatein/conf/configuration.properties文件中修改成如下所示,同时,下载mysql-connect-java.jar``jar包,放入$GATEIN_HOME/lib目录下。1
2
3
4
5gatein.idm.datasource.name=jdbcidm
gatein.idm.datasource.driver=com.mysql.jdbc.Driver
gatein.idm.datasource.url=jdbc:mysql://localhost:3306/jdbcidm_${name}
gatein.idm.datasource.username=root
gatein.idm.datasource.password=123在
$GATEIN_HOME/conf/server.xml的<GlobalNamingResources></GlobalNamingResources>节点中声明绑定的数据源,添加如下,字段含义可参考该文,注意,数据库名必须为jdbcidm_portal,且需要提前手动创建,无法自动创建,但是GateIn Portal会自动创建用户相关表:1
<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" logAbandoned="true" maxActive="20" maxIdle="10" maxWait="10000" minEvictableIdleTimeMillis="60000" name="exo-idm_portal" password="123" removeAbandoned="true" removeAbandonedTimeout="10" type="javax.sql.DataSource" url="jdbc:mysql://localhost:3306/jdbcidm_portal" username="root"/>
在
GateIn Portal与CAS整合后,账户系统将由GateIn Portal接管,也就是说,如果GateIn Portal服务没有开启,则CAS Server将无法进行认证。在
$GATEIN_HOME/conf/server.xml的Host元素下添加ServletAccessValve,如:1
2
3
4
5
6
7<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.gatein.sso.agent.tomcat.ServletAccessValve" />
<!-- SingleSignOn valve, share authentication between web applications
...其目的是开启
SSO组件,将其加入Catalina容器的请求处理管道中,这样,SSO组件将有机会处理每一个Request请求。
修改portal项目根路径
GateIn portal项目的默认网址格式为:{ip}:{port}/portal/*,如果我们想把根路径的portal改成其他的,如ots-portal,并不能简单的像其他Tomcat``webapp一样,直接修改目录名即可,因为portal有多个应用依赖,且portal关键字还作为容器名等在整个生命周期中起作用,最终经过大量分析测试,实现了更名,接下来,将总结修改的配置文件:
$GATEIN_HOME/conf/jaas.conf:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17gatein-domain {
org.exoplatform.web.login.FilterDisabledLoginModule required
portalContainerName=ots-portal
realmName=gatein-domain;
org.gatein.security.oauth.jaas.OAuthLoginModule required
portalContainerName=ots-portal
realmName=gatein-domain;
org.gatein.sso.integration.SSODelegateLoginModule required
enabled="#{gatein.sso.login.module.enabled}"
delegateClassName="#{gatein.sso.login.module.class}"
portalContainerName=ots-portal
realmName=gatein-domain
password-stacking=useFirstPass;
org.exoplatform.services.security.j2ee.TomcatLoginModule required
portalContainerName=ots-portal
realmName=gatein-domain;
};$GATEIN_HOME/gatein/conf/configuration.xml:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<object-param>
<name>portal</name>
<object type="org.exoplatform.container.definition.PortalContainerDefinition">
<!-- The name of the portal container -->
<field name="name">
<string>ots-portal</string>
</field>
<!-- The name of the context name of the rest web application -->
<field name="restContextName">
<string>rest</string>
</field>
<!-- The name of the realm -->
<field name="realmName">
<string>gatein-domain</string>
</field>
</object>
</object-param>$GATEIN_HOME/webapps/ots-portal/WEB-INF/web.xml:1
2
3
4
5<display-name>ots-portal</display-name>
<context-param>
<param-name>org.exoplatform.frameworks.jcr.command.web.fckeditor.digitalAssetsWorkspace</param-name>
<param-value>ots-portal</param-value>
</context-param>$GATEIN_HOME/webapps/ROOT/index.jsp:1
2
3
4<%
response.setStatus(response.SC_MOVED_TEMPORARILY);
response.setHeader("Location", "/ots-portal");
%>- 最后,当然同样需要将
portal目录名改为ots-portal。
如上修改之后,就可以通过网址{ip}:{port}/ots-portal/*来进行访问了。
注意点
更改根目录之后,其认证相关信息存储的库名将由jdbcidm_portal变为jdbcidm_ots-portal。
参考
- https://www.ibm.com/developerworks/cn/opensource/os-cn-cas/
- https://www.exoplatform.com/docs/public/index.jsp?topic=%2FPLF35%2FADM.Configuration.Connect_To_A_Production_Database.html
- https://repository.jboss.org/nexus/content/groups/public/org/gatein/sso/sso-packaging/1.4.1.Final/sso-packaging-1.4.1.Final.zip
- http://www.cnblogs.com/vhua/p/cas_1.html
- https://developer.jboss.org/wiki/ChangeGateInContextPath