撇开安全性的问题,从实现单点登录的角度来说,cookie在IE下的最大的问题就是无法实现跨域共享.
举个例子来说:
A和B是两个不同的系统,分布在不同的机器上,ip不同,域名不同,
A:www.a.com b:www.b.com,我最初的想法是如果在A系统登录成功后,访问B一次,让浏览记录B的Cookie,这样下次访问B的时候可以判断下Cookie,如果有的话,从Cookie中取出相关的信息,让其自动登录.但是后来发现这种做法在Firefox下可以工作,但是在IE下不行,后来受了网上一篇介绍搜狐通行证单点登录文章的启发,找到了问题的所在,需要在Response中加入一段特别的Header. P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR",这样才能正常写入.
解决了这个问题,实现思路基本上就理清了.先介绍下我们的系统,j2ee,ssh框架,通过session保存权限信息的,使用Cookie的目的仅仅是为了实现单点登录.还是用上面的例子,步骤如下.
1. 在A系统登录成功后的页面上,把需要传到B的信息传到页面上.
String userId = 从session中取出;
request.setAttribute("userId",userId);//用户名
request.setAttribute("timeout", super.getHttpRequest().getSession().getMax InactiveInterval());//session最大活动时间
login成功后的页面
例子中只是将当前用户的账号和cookie活动时间传递到B系统.
2. B系统Cookie写入当前浏览器
String userId = super.getHttpRequest().getParameter("userId");
Integer timeout = Integer.valueOf(super.getHttpRequest().getParameter(" timeout"));
target = new Cookie("SSO_userId",userId);
target.setPath("/");
target.setMaxAge(timeout);//设置cookie活动时间
super.getHttpResponse().setHeader("P3P","CP=\"NON DSP COR CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa CONa HISa TELa OTPa OUR UNRa IND UNI COM NAV INT DEM CNT PRE LOC\"");
super.getHttpResponse().addCookie(target);
返回一个空白页面或者改成从页面上写入都可.
3. 这样A系统登录后浏览器就保存了B系统的Cookie,下次访问B系统时就可以判断Cookie的存在,如果存在,取相关的权限信息存入Session,一定要在鉴权跳转之前判断Cookie.可以通过拦截器实现.
4. A系统注销后的页面,也要访问B系统的相关链接,把B系统的Cookie清除掉.
注销后页面
B系统
String userId = super.getHttpRequest().getParameter("userId");
Cookie[] cookies = super.getHttpRequest().getCookies();
super.getHttpResponse().setHeader("P3P","CP=\"NON DSP COR CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa CONa HISa TELa OTPa OUR UNRa IND UNI COM NAV INT DEM CNT PRE LOC\"");
if(cookies!=null)
{
for (int i = 0; i < cookies.length; i++)
{
Cookie c = cookies[i];
if(c.getName().equalsIgnoreCase("SSO_userId"))
{
userId = c.getValue();
if(c.getName().equalsIgnoreCase("SSO_userId")
&&c.getValue().equalsIgnoreCase(userId))
{
c.setMaxAge(0);
super.getHttpResponse().addCookie(c);
}
}
}
}
遗留问题:
1.由于是通过session保存权限信息,登录A系统,关闭浏览器,B系统Cookie清除,再次打开浏览器访问A是可以的,但是访问B就不行了,Cookie已清除.
2.登录A系统,一直操作直至保持session不过期,一段时间后B系统Cookie过期被清除掉,但A系统仍可以访问。
关于这两个问题,结合我们页面用的架构(frameset),有一种方法可以解决,就是在最下面版权页面(最下面frameset)上做工作,将session的最大活动时间getMaxInactiveInterval传到页面,利用html meta标签的自动刷新功能根据活动时间定时刷新
<meta http-equiv="refresh" content="<%=request.getParameter("timeout")%>;
url=http://www.b.com:8080/job/login!cookieSet.ilf?userId=<%=request.get Parameter("userId")%>&timeout=<%=request.get Parameter("timeout")%>">
还有一点负面效果,就是浏览器下方状态栏会定时出现一次进度条,一闪而过.
多站点整合—单点登录简单方案
http://www.liuyebo.com/archives/200801/458.html
用P3P header解决iframe跨域访问cookie
http://blog.csdn.net/wonder4/archive/2008/02/27/2125804.aspx