一个单点登录问题,请banq和J道友指教。

场景:
有www.a.com(A), www.b.com(B)和www.c.com(C)三台主机。 A主机部署了appA应用,B主机部署appB应用,C主机部署了单点登录认证服务器应用。
appA和appB通过主机C做基于Cookie的单点登录应用。

问题描述:
假如以下条件已成立: 主机A和主B都已成功向认证主机C获得了认证票据,并通过认证票据从认证服务器C获得了会员信息,同时在本地(appA和appB)内存维护了一份票据和关联的会员登录信息,目的是避免每次都向认证服务器请求会员信息。
本人想用认证服务器C的session来维护会员登录状态的活存周期,也就是当证服务器C的session过期销毁事件里加上向各客户端(appA,appB)发出注销通知消息。这样一来,我想到会存在一个问题:假如会员只是在认证时请求了1次服务器C,之后只访问appA或aapB, 那岂不是造成会员一直在使用系统(因为一直在访问aapA\aapB), 但服务器C的session却因一直没检测到有会员的请求而过期,从而引起登录状态的注销?

不知我描述是否清楚,其实我是想寻找一种管理认证票证(或是说登录状态)存活周期的方案。请大家指教。

在每个应用本地维护一份会员登录状态信息,虽然可以避免每次都向服务器请求,但也引起其它问题,假如集群环境下,appA应用部署在1.1.1.ip1和1.1.1.ip2两台主机上,当认证服务器注销了登录状态,向appA发送通知,要求aapA也注销,但集群环境下,是不是只能注销1.1.1.ip1或是1.1.1.ip2其中一台主机?
不知我的理解正不正确?

能否这样,将会话交与被登录的应用维护如何?

2010年07月01日 17:39 "chuangsheng"的内容
能否这样,将会话交与被登录的应用维护如何? ...

能否说详细点?

2010年07月01日 10:44 "sonnylys"的内容
但服务器C的session却因一直没检测到有会员的请求而过期,从而引起登录状态的注销? ...

使用terracotta之类分布式缓存来进行session在a b c之间同步复制。

c向a b发送消息 a b看到消息 再比较指定用户是不是该注销 并同时返回给c一个消息 c看到返回也许是真的注销该用户 也许是更改用户信息

我不知道你单点登录为什么要这要做。现在一般的方案是用memcache等做分布式缓存。具体怎么做你可以去

到网上找找。

但是你一定要这么做也是有办法解决的。 很简单你不就是怕用户从c认证后,就不再访问c了。只访问a,b了。

很简单的办法。你可以在你的 a,b的每一个页面里嵌入一小段c域上的资源,比方说一段js ,一张小图片等等。

不就可以。

2010年07月04日 22:18 "tianqiq"的内容
很简单的办法。你可以在你的 a,b的每一个页面里嵌入一小段c域上的资源,比方说一段js ,一张小图片等等。

不就可以。 ...

用js我有想过的,如ajax异步去请求c,但a,b应用里的页面的document里的cookie并没办法拿到c服务器的session id,这样用ajax发过去的请求,每次都是不同的session.

用session的生命周期来管理票据存活期及会员登录状态也不好实现,目前遇到问题是当session注销事情里并没法获取到cookie里的票。还有个办法是将session id作票据,当session注销时,在监听事情里就可以使用类似如下实现代码:
public void sessionDestroyed(HttpSessionEvent event) {
SSOServer server = ....
server.timeout(event.getSession().getId());
}

////这样在单认证服务器环境下是没问题的,但在集群环境下就有问题了:注销的session 不一定是生产ticket时的session。

2010年07月02日 17:37 "sabbath"的内容
c向a b发送消息 a b看到消息 再比较指定用户是不是该注销 并同时返回给c一个消息 c看到返回也许是真的注销该用户 也许是更改用户信息 ...

假如a,b主机是集群环境下的相同应用,使用的域名都是www.abc.com, 那么,当c发消息的时侯,也就是请求www.abc.com,那么这个消息就只能到达a或者b其中一台主机,而另外一台就没法接收到c的消息。

不知我的理解正确不?

2010年07月04日 22:18 "tianqiq"的内容
我不知道你单点登录为什么要这要做。现在一般的方案是用memcache等做分布式缓存。具体怎么做你可以去

到网上找找 ...

有没这方面的具休方案哦,能否提供参考参考??

我简单说下原理:

我们知道,事实上服务器怎么找到一个用户的session是通过一个储存在

客户的一个cookie session_id来进行的。 一般情况下。我们有多个站

时。用户访问的每一个站都会是一个不同的session__id 。这是

http服务器的基本工作。 那么如果能把各个站的session_id统一起来。

并把session放到一个独立地方。是不是就可以使多个站共享session了。

要实现也非常简单的。 比如说a,b,c3个站。我想让用户登陆任何一个站

都能同步到另外2个站。 我可以这样做。当用户首次访问我们a站上的

index时。我们在自己设置一个cookie作为这个客户的session_id(注意

这里指的不是http服务器默认的那个session_id,其实也行)我们可以

在index的页面中把生产的这个session_id 发送给b,c上的一个处理页

面(比方说我们在index中嵌入一个jsp页面什么不输出,就设置一个

cookie )并也将这个session_id设置到用户浏览器cookie中。 这个时

候,我们的每一个站都有了一个相同的cookie了session_id。我们可以

将这个cookie作为标示,将用户的信息,保存至一个map里。这个地

方map每个站都可以访问。我们产生的sessin_id做为key。用户的信息作为value。 我们的每一个站只用拿我们产生的那个cookie session_id

就去那个map里取用户的信息。而memcache就是一个这样的分布式缓存

那key取value 很适合做这个。

可能我表达不行, 不晓得你懂了没。

2010年07月06日 14:12 "tianqiq"的内容
我们可以

在index的页面中把生产的这个session_id 发送给b,c上的一个处理页

面(比方说我们在index中嵌入一个jsp页面什么不输出,就设置一个

cookie )并也将这个session_id设置到用户浏览 ...

谢谢tianqiq的详细描述。

当a,b,c为跨主域时怎么做到使用相同的cookie? 当访问a时,重定向至b,然后再重定向至c?
还有个不是很确定的问题:假如域名www.abc.com 部置了同样的应用主机x和主机y来做集群。当用户访问www.abc.com时在x产生了session id 产生cookie给客户端,当客户再访问www.abc.com请求指向了y,y是否会用在x产生的session id来生成一个session?

看来我的表达方式确实是差了。

比方说a站的一个页面: login

在login的页面里有这样一段代码.

<img src="www.b.com/setcookie.jsp?session_id=(统一产生的id)" sytle="displsy:none"/>
<img src="www.c.com/setcookie.jsp?session_id=(统一产生的id)" sytle="displsy:none"/>
<img src="www.d.com/setcookie.jsp?session_id=(统一产生的id)" sytle="displsy:none"/>
<img src="www.e.com/setcookie.jsp?session_id=(统一产生的id)" sytle="displsy:none"/>

而setcookie.jsp他的作用主要做用就是当根据传递过来的session设置这个session_id到客户端浏览器。

这个时候b,c,d,e是不是都有了一个统一的session_id了。不过在b,c,d,e的setcookie.jsp里应该设置p3p头 。

其实也就在http响应里,添加一个响应头。说明我是好人。 请接受我的cookie 呵呵。

不然在ie下是无法成功的。ie默认不接受第3方cookie的。

2010年07月07日 10:59 "tianqiq"的内容
不过在b,c,d,e的setcookie.jsp里应该设置p3p头 。

其实也就在http响应里,添加一个响应头。说明我是好人。 请接受我的cookie 呵呵。

不然在ie下是无法成功的。ie默认不接受第3方cookie的。 ...

我的知识点在这里断层,谢谢tianqiq的回答,我先了解下p3p头。非常感谢。