`
fandayrockworld
  • 浏览: 308913 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

关于CAS实现单点登录的思考

阅读更多

      最近要做单点登录,于是研究了两天CAS,对用户注册这个问题很纠结,有以下两种方式,不知哪个更好,期待大家讨论。

 

      1、Server端有DB,自己做好用户注册的实现,将接口提供给各个Client端(具体用什么方式让Client端调用是个难点,难点1)。

       这样的话,用户登录某一应用(CAS中的Client端)时,会被拦截,转到Server端,在Server端读数据库进行验证,验证通过后,返回到Client端,然后Client端再读自己的数据库,取出用户的信息(此处很纠结,因为各个Client的用户实体的属性是不一样的,比如有的Client端的用户有手机号这一属性,有的则没有,所以综合了一下,只希望在Server端存用户的用户名和密码)。

 

      2、Server端无DB,注册时到各Client端只把用户信息保存到各自的DB。

      这样的话,用户登录某一应用(CAS中的Client端)时,会被拦截,转到Server端,Server端根据请求的不同判断该调用哪个Client的DB进行验证(难点2),此处又要有分支了:

      1)、验证的时候把用户信息读出来,验证通过后,将用户信息直接传给Client端(难点3),这样Client端就不用再读DB提取用户信息了。

      2)、验证的时候不读用户的信息,验证通过后,返回到Client端,Client端再读用户信息。

 

大家觉的用什么方式好一些?并希望大家对标红的三个难点进行讨论。

 

 

这个帖子不错:http://www.iteye.com/topic/165313

 

BTW:

感谢大家的热情参与,特别鸣谢:wad12302、denger 、fallen_lord、lovit

大家可以看一下他们的发帖,会得到不少信息。

扩展CAS等具体做法请参照fallen_lord的发帖。

稍后我会参照他们的观点作出整理,loading..........

 

-----------------------------------分割线-----------------------------------------------------

 

现在正在实现着,等实现好了再把方案完整的贴出来。

采用的方式是REST,谢谢denger的建议,至于CAS怎么集成REST,大家可以去看denger博客上的文章:http://denger.iteye.com/blog/973068

 

loading...........

 

分享到:
评论
74 楼 o0虫子0o 2014-06-03  
我想问问你的注册做好没?denger写的cas的文章我都看了,你们说的用rest在cas服务端来实现,到底怎么做呢?能不能把代码发出来啊?
73 楼 honglei0412 2014-06-02  
denger 写道
wad12302 写道

这个的第3点 只是 应为 当时 说的 采用多库链式查找用户信息,那么如果没有数据同步或者同义词之类的(集成原有系统),,在各个系统中可能没有该用户信息,访问某些特定东西 肯定涉及权限问题,所以这个权限要怎么兼容进来(没有采用统一管理用户信息,当然像前面说的,对多个系统进行用户统一管理后这种问题就不存在)


还有就是讨论中所说的,cas 只涉及到单点登录 不涉及其他,我个人认为这样理解不妥
就职能来说 只是验证,但是还有一个重点就是 验证之后呢,这就要考虑到这个系统的改动问题
不能单单应为一个功能而忽略了整个系统现在的状态,怎么做到集成进来了可以把改动降低最小(功能涉及)
毕竟新的系统好解决,集成原N年系统就要考虑
所以大家讨论的不应只是限在点点登录而应该考虑所涉及范围


为什么大家一直说
引用
cas 只涉及到单点登录 不涉及其他
,其目的就是
引用
做到集成进来了可以把改动降低最小
,由其是对于老系统来说更是如此。 CAS 只涉及单点登录的主要是降低应用系统与 CAS 的偶合度,当我需要将某个应用系统集成至 CAS  中时候,我只需要修改它的登录处理、注销、是否已经登录的校验(如果通过Filter的话基本不需要修改,只需要增加未登录跳转的地址即可,并且cas -client提供好很好扩展机制,如自定义登录成功之后的业务逻辑,自定义登录失败的业务逻辑,从Session中获取当前登录用户,这些都可以自定义)。 其它 一般都不需要进行修改,你根本不需要管现在系统的业务状态(当然,如果你权限偶合度及设计是足够烂就没得说了,我以前见过直接在 jsp 上判断是否允许访问校验代码)。 我们以前整合过一个公司购买的 支付系统,它的权限机制及业务也是非常的复杂的,但是实际过程改动实际上非常小~



假如说我现在有多个应用系统每个应用系统中都有一套用户名、密码,而且每一个应用的用户名密码都不一样这种情况下使用CAS请问如何

进行处理哈?在不改变之前应用系统的用户名、密码情况下是如何处理的?
72 楼 honglei0412 2014-06-01  
newchq 写道
rambler 写道
建一个集中注册和维护的用户信息库,仅存放通用信息,例如身份证号、员工编号、姓名和口令等等,CAS在此用户库上进行集中认证。
    当用户通过CAS验证访问客户端应用时,CAS传递用户凭证(身份证号、员工编号、姓名),客户端须判断该用户凭证是否在本系统中存在,如果已存在则自动进入系统,并遵循客户端权限管理;
    如果用户凭证在客户端应用中没有保存过,则根据业务需要判断CAS提供的用户通用信息是否足够用,若够用直接后台写入本系统用户表,然后进入系统;如果还需补充其它信息则弹出注册页面,显示通用信息,用户补充填入其它信息后提交,这样用户下次再访问本系统时就可以自动进入;
    如果用户在业务系统中原本就有账户信息(在单点登录系统实施前的旧系统),则在上诉注册页面让用户选择绑定原有账户,输入原客户端应用的登录名和登录口令,验证通过后将用户的CAS凭证和旧账户绑定保存在客户端用户表中,这样用户再次访问客户端应用时就可以使用原账户的相关信息。


这个方案可行并且已经完成,和这位老兄说的一摸一样


假如说我现在有多个应用系统每个应用系统中都有一套用户名、密码,而且每一个应用的用户名密码都不一样这种情况下使用CAS请问如何

进行处理哈?在不改变之前应用系统的用户名、密码情况下是如何处理的?
71 楼 ae6623 2013-04-25  
按照楼主所说,已经搞定多数据源验证用户模式,正在尝试改写相关用户验证类,希望有类似研究的朋友来和我一起继续探讨,百度链接放出来:SSO单点登录系列2:cas客户端和cas服务端交互原理动画图解,cas协议终极分析 http://hi.baidu.com/ae6623/item/b05ae8501510e93094eb05ae

最后再次感谢楼主,我也会写一篇教程出来,作为SSO单点登录系列3:配置数据源完成cas-server端自定义验证登陆。
70 楼 qq461149132 2012-09-25  
lz,请问你的单点登录系统做好了吗?把详细方案说下哈。谢谢
69 楼 javaAndNet 2012-05-22  
fandayrockworld 写道
wad12302 写道
这个了解。

主要是现在 想了解怎么 分配注册这个问题:

比如我有多个系统进行合并,并且每个系统 都有自己的用户信息存储表

系统A   a_user

系统B   b_user

那么 现在我使用单点登录时候 怎么判断查询那个 表的用户信息好,有什么策略没有。

应为cas 提供验证,但是登录时候 用户名和密码最终是用哪里的?


从你问的这些问题看,你根本就没深入了解一下CAS,建议多上网上查查,另外,我文中最后的那个链接挺不错的,仔细看完了估计你就了解的差不多了。

对于你的问题:

找到deployerConfigContext.xml这个文件,在beans标签的下面加上以下两个数据源(注意,所加的这两个数据源必须是beans下面的第一个bean):
<bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource" destroy-method="close">
       <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
       <property name="url"><value>jdbc:mysql://192.168.1.244:3306/cas</value></property>
       <property name="username"><value>root</value></property>
       <property name="password"><value>root</value></property>
	</bean>
	<bean id="dataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource" destroy-method="close">
       <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
       <property name="url"><value>jdbc:mysql://192.168.1.245:3306/cas1</value></property>
       <property name="username"><value>root</value></property>
       <property name="password"><value>root</value></property>
	</bean>


然后找到:
<bean
					class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />

把他注释掉,加上以下两个:
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
				        <property name="sql" value="select password from a_user where username=?" />
				      <property name="dataSource" ref="dataSource1" />
				</bean>
		        <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
				        <property name="sql" value="select password from b_user where username=?" />
				      <property name="dataSource" ref="dataSource2" />
				</bean>

修改成这样就可以了。

然后:

假如a_user中有一个用户:auser,b_user中有一个用户buser,这样你无论用哪一个用户登录,CAS就会先查a_user,如果用户名密码都正确,那么就通过,如果a_user中验证失败,那么CAS就会再查b_user,用户名密码都正确就算通过了,此时不正确,就算这次登录验证没通过。

如果现在还不知道怎么回事,那我就哭了。。。。。
另外,千万不要成为伸手党,自己查资料才是王道。


我在deployerConfigContext.xml中配置了如下:
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
				        <property name="sql" value="select password from a_user where username=?" />
				      <property name="dataSource" ref="dataSource1" />
[color=red][size=x-large]<property ref="passwordEncoder" name="passwordEncoder"/>[/size][/color]
				</bean>
		        <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
				        <property name="sql" value="select password from b_user where username=?" />
[color=red][size=x-large]<property ref="passwordEncoder" name="passwordEncoder"/>[/size][/color]
				      <property name="dataSource" ref="dataSource2" />
				</bean>

为什么就不行了?如果用第一个bean的username和password登录就没问题,用第二个bean的username和password登录就有问题呢?为什么?求解啊……
68 楼 antonia 2011-06-16  
单点登录这个功能还是天翎myApps柔性软件平台做的比较出色
67 楼 wu_quanyin 2011-05-19  
不同的系统拥有着自己本身的用户信息,不可能通用,,,,

但是在用户登录验证时,Cas有提供一个验证链,可以进行多个数据表验证。。
66 楼 mengke 2011-05-16  
cas只用作sso
用户注册管理可以考虑单独作为独立的应用--用户管理,  用户信息同步问题可以让各个应用系统提供接口,在用户管理系统中通知各应用系统(可以考虑使用观察者模式)
65 楼 lovit 2011-05-11  
haojiahero 写道
fandayrockworld 写道
lovit 写道

这个注册功能,就像登录面,根本就不用考虑不同的语言啊,你登录页不是也在CAS Server端吗??

假如现在有两个client端,分别是PHP和java做的,那么你在各个client端调用CAS现有的功能,要加入CAS提供的不同的client端实现(PHP的加PHP的client端实现,JAVA的加JAVA的client端实现),所以,你要是再给CAS加功能的话,那请问,你是不是要在这些CAS提供的client端实现里也要加东西才能调用?
请仔细考虑一下。。。


cas不负责业务功能吧。。。  主要还是注册和登录验证  其他的东西你干嘛放进去!

这位兄弟,这不就是在讨论注册要不要加在CASServer端吗?都不看,还在那激动,呵。。
64 楼 haojiahero 2011-05-10  
fandayrockworld 写道
lovit 写道

这个注册功能,就像登录面,根本就不用考虑不同的语言啊,你登录页不是也在CAS Server端吗??

假如现在有两个client端,分别是PHP和java做的,那么你在各个client端调用CAS现有的功能,要加入CAS提供的不同的client端实现(PHP的加PHP的client端实现,JAVA的加JAVA的client端实现),所以,你要是再给CAS加功能的话,那请问,你是不是要在这些CAS提供的client端实现里也要加东西才能调用?
请仔细考虑一下。。。


cas不负责业务功能吧。。。  主要还是注册和登录验证  其他的东西你干嘛放进去!
63 楼 guanlicome 2011-05-09  
jsp_boy 写道
用一个LDAP服务器,如Active Directory来集中管理用户信息。CAS跟LDAP结合进行身份验证,各个应用自己维护各自的用户信息。当然这会涉及到各个应用与LDAP服务器之间用户信息同步的问题。


LDAP实现CAS是个标准的企业级实现,
在互联网上就不好用了。
62 楼 dary_zhou 2011-05-08  
CAS做单点登录已有很我现成的客户端,做CAS前,最好先统一用户。
61 楼 lance4t 2011-05-06  
“所以,我觉得还是在访问B系统时,B系统再与Server端通讯应该是比较好的解决方案,就像CAS一样。”
赞同这种,没接触过CAS,在业务上,我是这样理解的:
A系统和B系统都有自己的角色权限管理等,但这些都保存在Server上,
初次访问A登陆的时候,请求Server看是否登陆,如果已经登陆就返回A系统所需的用户角色权限信息,存放在A的session,Server只记录此用户已经登陆,不需要在Session保存任何跟A系统有关的信息,包括用户权限等信息。
访问B同理,请求Server,Server判断此用户是否登录,如果已经登陆,取出B系统所需的角色权限等信息,返回给B,B保存信息在自己系统的Session,供自己使用。

在某系统下登出的时候,清理当前系统Session,通知Server用户已经登出,Server注销用户登出信息。

如此的话,用户每当第一次访问某系统的时候,此时当前系统Session应该是空的,都去Server检查一下登陆状态。

Server的Session只存已登录用户的用户名,收到登出通知就删掉相应的用户名。
这样Server的内存应该能容纳足够多的用户登陆状态信息,如果不行就考虑持久化到硬盘。

上面只是我纸上谈兵的看法,大家多包涵。。。
60 楼 lovit 2011-05-04  
<p> </p>
<p>
wuyakenihao 写道
你好关于这个CAS我没了解过,但是我们的网站全部实现了SSO,我们是给移动做项目的,系统与系统之间就实现这个功能,其实这个不用想的太麻烦,只要明白其中的原理就可以了,我给你说下我们系统是如何实现吧,其实告诉别的系统你在这个系统登录关键就是你的会话要统一。我们是有一个server断当用户在系统A不管登录否这个时候要和server建立一个请求,目的是为了保证会话的统一。这个时候如果用户登录了就告诉server段用户在系统A登陆了,这个时候你会发现,你当前系统A和server的会话是统一的,剩下就是有你的server端告诉别的系统你在A登录了。在别系统中注册你的用户信息,这样你只要在系统A登录点击到别的系统也是登录状态,不知道你理解我的意思不?
</p>
<p> </p>
<p> </p>
<p>的确不是很明白,</p>
<p> </p>
<ol>
<li>为什么在访问B系统时,B系统就是登录状态呢,你的SessionId或用户名是怎么传上去的?</li>
<li>Server端通知是可以实现,通知后我不知道您采用的什么方式,但是如果采用Session方式来管理,如果用户从来都不访问B系统或加入单点登录的系统很多个,会不会影响性能?再者说,如果我在操作A系统时,一直不访问B系统,会话是不是超时了?等超时后,我再访问B系统时,怎么办呢</li>
<li>加入新的单点登录系统,服务器端还要配置修改吧(因为您的实现是Server去主动通知各子系统的)</li>
</ol>
<div>所以,我觉得还是在访问B系统时,B系统再与Server端通讯应该是比较好的解决方案,就像CAS一样。</div>
<p> </p>
<p> </p>
59 楼 wuyakenihao 2011-05-04  
你好关于这个CAS我没了解过,但是我们的网站全部实现了SSO,我们是给移动做项目的,系统与系统之间就实现这个功能,其实这个不用想的太麻烦,只要明白其中的原理就可以了,我给你说下我们系统是如何实现吧,其实告诉别的系统你在这个系统登录关键就是你的会话要统一。我们是有一个server断当用户在系统A不管登录否这个时候要和server建立一个请求,目的是为了保证会话的统一。这个时候如果用户登录了就告诉server段用户在系统A登陆了,这个时候你会发现,你当前系统A和server的会话是统一的,剩下就是有你的server端告诉别的系统你在A登录了。在别系统中注册你的用户信息,这样你只要在系统A登录点击到别的系统也是登录状态,不知道你理解我的意思不?
58 楼 yn5411 2011-05-03  
socket解决一切
57 楼 sjbrising 2011-05-03  
单点登录就是要拥护统一管理,从而才能做到统一认证。如果不统一管理用户,而是在各个应用系统当时分别管理用户。那用户提交认证信息的时候,你该去那个应用系统去判定用户的认证信息是否正确呢?
而且,在现实中,很多的应用系统不会开发数据库权限给你的。如果出了问题,责任也不好判定。
56 楼 newchq 2011-04-30  
rambler 写道
建一个集中注册和维护的用户信息库,仅存放通用信息,例如身份证号、员工编号、姓名和口令等等,CAS在此用户库上进行集中认证。
    当用户通过CAS验证访问客户端应用时,CAS传递用户凭证(身份证号、员工编号、姓名),客户端须判断该用户凭证是否在本系统中存在,如果已存在则自动进入系统,并遵循客户端权限管理;
    如果用户凭证在客户端应用中没有保存过,则根据业务需要判断CAS提供的用户通用信息是否足够用,若够用直接后台写入本系统用户表,然后进入系统;如果还需补充其它信息则弹出注册页面,显示通用信息,用户补充填入其它信息后提交,这样用户下次再访问本系统时就可以自动进入;
    如果用户在业务系统中原本就有账户信息(在单点登录系统实施前的旧系统),则在上诉注册页面让用户选择绑定原有账户,输入原客户端应用的登录名和登录口令,验证通过后将用户的CAS凭证和旧账户绑定保存在客户端用户表中,这样用户再次访问客户端应用时就可以使用原账户的相关信息。


这个方案可行并且已经完成,和这位老兄说的一摸一样
55 楼 zhoushuping 2011-04-29  
进行单点登录必须先统一用户,建立用户认证的统一数据库。

相关推荐

Global site tag (gtag.js) - Google Analytics