java单点登录集成客户端
2 变更记录
版本
修改时间
修改人
修改内容
备注
3 产品介绍3.1 基本原理
一次完整的SSO认证如下图所示:
假设应用1(地址为http://192.168.0.100/sever1)和应用2(地址为http://192.168.0.101/server2)分别集成了SSO Client,SSO Server部署在192.168.0.10上。
Ø 从未登录系统的情况
用户访问应用1时,应用1将自动携带当前地址(HostUrl)重定向至SSO Server;SSO server 返回用户登录界面,待用户登录认证通过,将随机生成一个验证票据(Ticket)返回给用户,同时重定向至最初携带的应用1的地址(HostUrl);应用1将携带应用1的地址(HostUrl)和票据(Ticket)提交给SSO Server验证用户是否登录有效,验证通过后,最终返回访问页面。Ticket具有一定的存活周期。
Ø 应用1已经登录,应用2未登录
用户访问应用2时,应用2将自动携带当前地址(HostUrl)重定向至SSO Server;由于应用1已经登录,则SSO Server直接生成一个验证票证(Ticket)返回给用户浏览器,然后应用2将地址(HostUrl)和票据(Ticket)提交给SSO Server验证用户是否登录有效,验证通过后,最终返回访问页面。
Ø 系统退出登录
系统退出登录,必须使用SSO退出登录,否则不能保证当前应用退出登录,对其它系统生效。3.2 版本说明
单点登录客户端从版本2.1.0开始,bonc-sso-client-XX.jar不再包含cas-client-core.jar,因此在bonc-sso-client-2.1.0.jar及以上版本开始,需要用户注意添加cas客户端核心包cas-client-core.jar。3.3 文件说明
单点登录应用通常包括了以下文件, 其中"xxx"为版本号:
Ø bonc-sso-client-demo-xxx.war 单点登录客户端演示应用
a) bonc-sso-client-xxx.jar 单点登录客户端应用开发包
b) cas-client-core-3.2.1.jar 单点登录客户端cas客户端依赖包
c) commons-logging-1.1.jar 单点登录客户端应用开发包的依赖包
Ø bonc-sso-client-2.1.1-sources.jar 单点登录客户端本地会话实现源码参考4 部署4.1 环境要求
应用服务器:JDK6.0+,TOMCAT6.X或其他同等应用服务器4.2 测试环境部署
1. 假定单点服务端应用已经部署。
2. 修改bonc-sso-client-demo-xxx.war中的/WEB-INF/web.xml中的配置,配置内容如下,请仔细查看参数的解释:< listener >
< listener-class >
org.jasig.cas.client.session.SingleSignOutHttpSessionListener
listener-class >
listener >
< filter >
< filter-name > SSO Filter filter-name >
< filter-class >
com.bonc.sso.client.SSOFilter
filter-class >
< init-param >
< description > CAS客户端地址 description >
< param-name > serverName param-name >
< param-value > 127.0.0.1:8080 param-value >
init-param >
< init-param >
< description > CAS服务器地址全路径 description >
< param-name > casServerUrlPrefix param-name >
< param-value > http://127.0.0.1:8080/cas param-value >
init-param >
< init-param >
< description > CAS服务器登录地址 全路径 description >
< param-name > casServerLoginUrl param-name >
< param-value > http://127.0.0.1:8080/cas/login param-value >
init-param >
< init-param >
< description > 是否启用单点登出 description >
< param-name > singleSignOut param-name >
< param-value > true param-value >
init-param >
< init-param >
< description > 单点登录忽略校验URL description >
< param-name > skipUrls param-name >
< param-value > /out.jsp,.*.(css|js|jpg|jpeg|bmp|png|gif|ico)$ param-value >
init-param >
< init-param >
< description > 登录成功后的的用户信息准备 须实现com.bonc.pure.sso.client.ILoginUserHand 接口 description >
< param-name > loginUserHandle param-name >
< param-value > com.bonc.sso.client.impl.DemoAuthHandleImpl param-value >
init-param >
< init-param >
< description > 解决读取CAS server端返用户扩展信息中文乱码问题 description >
< param-name > encoding param-name >
< param-value > UTF-8 param-value >
init-param >
filter >
< filter-mapping >
< filter-name > SSO Filter filter-name >
< url-pattern > /* url-pattern >
filter-mapping >
3. 将bonc-sso-client-demo-xxx.war改名为client.war,然后拷贝到tomcat主目录下的webapps目录下。如果tomcat在运行状态,则会自动部署client应用,否则,请启动tomcat(window:执行tomcat主目录binstartup.bat;linux/unix:执行tomcat主目录/bin/startup.sh)。
4. 打开浏览器,在地址栏输入http://127.0.0.1:8080/client。如果正常的话,将转入单点登录服务器的登录界面:
5. 测试的用户名/密码只要是一致的,就可以登录成功,登录成功后,将进入如下界面:4.3 正式环境部署
1. 转入到客户端应用的开发环境下
2. 将bonc-sso-client-xxx.jar、cas-client-core-3.2.1.jar、commons-logging-1.1.jar拷贝到客户端应用的WEB-INF/lib目录下
3. 提取bonc-sso-client-2.1.1-sources.jar中的com/bonc/sso/client/demo/ IAuthHandle.java,参考DemoAuthHandleImpl实现一个适应本系统的实现类。IAuthHandle接口类中onSuccess方法是需要覆写的。/**
* 校验通过后,写本地会话
*
* @param request
* HttpServletResponse
* @param response
* HttpServletResponse
* @param loginId
* 登录用户ID,为用户在登录窗口的输入的ID
*/
boolean onSuccess(HttpServletRequest request, HttpServletResponse response, String loginId);
4. 修改客户端应用中的/WEB-INF/web.xml中的配置,同测试环境部署。
特别注意:需要将单点过滤器配置在所有过滤器的最前面,保证单点过滤器在过滤器链的最前面。
5. 测试,同测试环境。5FAQ5.1 如何从旧版本迁移
1、 删除之前的客户端应用中WEB-INF/lib/bonc_sso_client.jar
2、 参照章节"部署客户端应用"部署新的客户端应用5.2 部署后,访问应用报错
这一般是由于过滤器配置错误造成的。检查过滤器的各项配置是否正确,客户端是否能正常访问单点服务器。5.3 单点登录登录成功后,需要再次登录应用系统
造成此现象原因有2个:
Ø web.xml文件中没有配置相应的适合当前系统的com.bonc.sso.client.IAuthHandle实现类
Ø 如果是XFrame框架,则是登录Action没有判断当前session中是否存在有效用户,而是直接跳转到登录界面5.3.1 配置IAuthHandle实现
这说明单点服务配置成功,但是由于应用系统的session中没有相应的用户信息造成的。需要应用系统配置一个将用户信息写入本地session的一个实现类,接口为com.bonc.sso.client.IAuthHandle。系统提供3种实现供参考,并附上源代码:
适用框架
实现类
Pure框架
com.bonc.sso.client.impl.PureAuthHandleImpl
Xframe2.*框架
com.bonc.sso.client.impl.XframeAuthHandleImpl
返回更多用户信息
com.bonc.sso.client.impl.UserPrincipalHandleImpl
参数配置:
代码:
本地用户信息session接口:
其中loginId为用户登录时,填写的登录用户ID。5.3.2 修改LoginAction
其中红色圈起来的为新增:5.4 退出系统失效5.4.1 情况一
这是因为没有使用单点退出而造成的,正确的退出系统的url调用为:
Http://${cas-server}:${cas-server-port}/${cas-server-contentpath}/logout?service=curentservice
应该是cas单点服务器的根路径+/logout,此路径将不会重定向至你的单点应用,如果需要重定向至当前应用,应该将当前应用地址作为service参数附加在/logout后面。5.4.2 情况二
不能只对*.action进行过滤,过滤器应该对所有请求/*进行过滤,。配置如下:
< filter-mapping >
< filter-name > SSO Filter filter-name >
< url-pattern > /* url-pattern >
filter-mapping >
5.5 如何实现不通过单点就访问客户端应用的特定模块
将不需要通过单点认证就能访问的URL,配置在单点过滤器的skipsUrl中。SSOFilter中的doFilter会通过preFilter会对url进行判断,若当前url在skipsUrl中,则不再对该url进行单点认证。 5.6 加单点后集群配置问题5.6.1 集群问题
由于个别客户端应用的Apache采用jk_mod的集群方式,无法对tomcat内部的重定向的URL进行自动重写为apache的映射路径,因此客户端的表现为直接访问tomcat,但是用户初始访问是apache决定访问集群中的某个tomcat服务器,因此,负载均衡还是有效的。同时,由于同样的原因,造成客户端应用无法通过现有的apache集群来访问系统。
解决办法:可通过单点服务器的apache统一访问,同时,将客户端应用原有的apache安装proxy模块,使用proxy_html替换现有的jk_mod集群。5.6.2 proxy集群环境下,通过单点认证后报403错误问题
原因分析:直接访问应用根目录, apache会给用户分配一个 tomcat ,然后经过单点认证,apache重新转发时转发到新的tomcat,导致单点登录发放的凭证与当前tomcat不匹配造成的,tomcat未能正确的书写客户端cookie,导致转发错误。
解决办法:通过Apache的header模块,给通过apache转发至集群中的tomcat时,强制书写一个路由ID标识,从而使得apache能转发至正确的tomcat。并且将各个系统的index.html,index.jsp排除在单点之外。
如上海经分系统配置如下:RewriteRule ^/dss$ /dss/index.html [R,L]
RewriteRule ^/dss/$ /dss/index.html [R,L]
#dss
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/dss" env=BALANCER_ROUTE_CHANGED
BalancerMember http://134.78.5.38:8080/dss loadfactor=1 route=dss1
BalancerMember http://134.78.5.38:8090/dss loadfactor=1 route=dss2
ProxySet stickysession=ROUTEID
ProxyPass /dss/ balancer://dss/ nofailover=Off
ProxyPassReverse /dss/ balancer://dss/5.7 经过单点验证后,系统抛空指针异常
原因分析:单点验证的用户表和客户端应用的用户表不同步造成,单点验证的用户表中存在的用户在客户端应用的用户表中不存在。
解决办法:修改SSOFilter,增加判断,当不存在用户时,提示权限不足(此处代码已修改)。同时,修改IAuthHandle实现类中得onSuccess方法,在用户不存在时,返回false,以供SSOFilter判断使用。5.8 怎么能同时支持内外网访问
在实际部署中,会遇到内外网切换问题,此问题在之前的版本是通过修改配置的方式实现,当前,此方法已经废弃,改为通过通过apache反向代理解决内外网问题,相见apache反向代理配置
需要注意的是:单点登录客户端地址均配置应用部署地址,保证服务器相通即可。5.8.1 使用pure门户集成应用系统地址切换问题
在pure门户中配置应用系统管理的时候,系统的服务器地址应该配置为空。这样系统就可以默认取到当前访问的服务器地址(即门户apache的地址),当从外网访问时,取到的是服务器的外网IP。当从内网访问时,取到的是服务器的内网IP。然后通过apache对各应用做的proxy集群,分配tomcat,从而不会造成内外网切换问题。5.9 XFrame框架问题5.9.1 子系统重启后无限刷新
通过门户进入子系统,子系统服务重启后,会一直在"您已掉线,请重新登录的页面"的界面无限刷新,无法回退操作。
原因分析:此问题是由于子系统所使用的XFrame框架版本比较低,此版本中存在用户登录信息未及时写入数据库的bug,导致用户失败。
同样,在用A用户登录门户,点击子系统菜单后,换B用户登录再次点击改子系统菜单会出现记录数不唯一的错误也属于该问题才生的。
解决办法:由于框架版本比较低,为了减少直接升级至最新版本引起不可预见的问题,采用直接替换存在问题的部分代码。5.9.2 XFrame框架抛java.lang.NullPointerException
具体报错类CookieManage中的 Utils.getResponse().addCookie(c)行。
原因:由于老版的Utils.getResponse()方法直接调用的struts2的静态方法,此方法在没有经过struts2的拦截器的方法里面调用时,将抛出空指针异常。
修改办法:将CookieManage的方法内容注释