积极答复者
基于Webservice的SSO单点登录系统思路求解答

问题
-
各位老师好:
最近公司的几个系统要做一下整合,专门有一台服务器做为Webservice使用,提供身份认证等功能,在一般情况下使用还是可以的,但我想更进一步,做到SSO单点登录方式,如果在浏览器中已经登录了A系统,则输入B系统的地址时,也可自动进入,这二天也上网查了很多资料,但很多问题还是没办法想通,现将遇到的问题陈述一下,还请各位老师帮忙。
一、各服务器无域名或部分用户不使用域名。因为是内网应用,大家都已经习惯了使用IP地址登录,后来公司设置了一台DNS服务器,但大家还是直接使用收藏夹中的地址,也就是IP地址登录;服务器的网段也不完全相同,部分在10.123.22.*网段,部分在10.123.33.*,部分在10.234.44.*之类
二、设有三个应用,分别是A、B、C,在三台不同的服务器上,提供统一身份的服务器为S服务器,用户客户端U,现假设系统均为B/S系统,下一步可能会考虑扩大到C/S系统;
三、U计算机登录A应用,A应用向S服务器发webservice报文,S服务器通过验证后写cookies,;此时U计算机再次登录B应用,B应用向S服务器请求查看用户状态,S服务器读cookies,返回已有U用户登录(这一步失败了,代码如下:)
<WebMethod(Description:="验证用户登录信息")> _ Public Function UserLogin(ByVal LogonInfo As String) As XmlDocument '验证过程略过 Dim cookie As New HttpCookie("mysite") cookie.Values("uid") = Sid cookie.Values("uname") = Suname cookie.Expires = DateTime.MinValue HttpContext.Current.Response.Cookies.Add(cookie) Return HttpContext.Current.Response.Cookies("mysite")("uname") & "登录成功!" End Function
<WebMethod(Description:="验证用户是否已经登录")> _ Public Function UserStatus(ByVal StatusInfo As String) As XmlDocument '前面的过程略过 '如果用户未留下Cookies If String.IsNullOrEmpty(HttpContext.Current.Response.Cookies("mysite")("uid")) Then Return "用户未登录过!" End If Return HttpContext.Current.Response.Cookies("mysite")("uname") & "已登录!" End Function
首先这个cookies写到哪儿去了?还在S服务器上,还是写到A服务器上了?我原以为会写到U客户机上,后来发现好像不是这样,http是无状态的,会不会调用Webservice结束后,cookies就被删除了呢?
如果在A服务器的应用中,将返回的uid加到B、C应用的URL中,是没有问题的,但如果是客户在浏览器中手动输入怎么处理呢?
我还想过在数据库中建一个表,用户登录时写入最后活动时间、IP地址,然后有请求时看一下IP地址和最后活动时间来判断是否是本机,这种的话还可以很好的让C/S系统使用,但又有一个问题,内网用户一般来说IP地址是固定的,但万一有使用了小路由的,数台计算机都是同一IP地址怎么判断呢?
比如QQ,在本机上登录了一个QQ,使用它的服务(QQ官网或可以使用QQ帐号登录的论坛等),它都能准确的知道你是谁,不会因为你在网吧与数十上百人用同一个IP地址就判断错误,无论用户打开的是IE还是Chrome,都能获取已登录的用户,它的原理是如何实现的呢?
还有,如果U客户端与S服务器之间有防火墙,只能A、B、C服务器访问S服务器,又该如何处理呢?是使用cookies好,还是使用数据库方式好?
希望老师们给予指点,提供思路或参考文档,谢谢。
2012年11月19日 6:31
答案
-
你好,
目前流行的做法是使用OAuth 或者WS-Federation Passive Profile提供SSO.可以使用WIF来做一个SIS,用WS-Federation Passive Profile来实现.这个都是有例子可以参考的. 建议参考:
http://msdn.microsoft.com/en-us/magazine/ff872350.aspx
http://www.microsoft.com/en-us/download/details.aspx?id=14347
Allen Chen [MSFT]
MSDN Community Support | Feedback to us
- 已编辑 Allen Chen - MSFT 2012年11月26日 3:13
- 已建议为答案 Decker Dong - MSFT 2012年11月26日 8:47
- 已标记为答案 Decker Dong - MSFT 2012年11月28日 2:32
2012年11月26日 3:09
全部回复
-
不建议用IP,因为IP会动态随机分配,不是固定的。
我的看法:
1)你弄一个User表,每一个User应该有一个固定的Id(类似QQ号),用这个号+口令登陆系统。
2)User表中应该有一个State状态(默认0,表示尚未登陆)。
3)任何一种方式登录(验证用户Id+口令成功之后),设置State为1(已经登陆)。这样的话其它机器一旦在登陆,则判断State是否1,是1的话不允许再登陆。
4)这里考虑一点的是:如果Web方式不是通过点击“注销”方式而是直接点击右上角“叉”关闭,那么你应该使用该js或者jQuery方法,利用WebService或者WCF方法把当前用户注销掉:
$(window).unload(function(){
alert("Goodbye!");
});2012年11月20日 5:24 -
你好,
目前流行的做法是使用OAuth 或者WS-Federation Passive Profile提供SSO.可以使用WIF来做一个SIS,用WS-Federation Passive Profile来实现.这个都是有例子可以参考的. 建议参考:
http://msdn.microsoft.com/en-us/magazine/ff872350.aspx
http://www.microsoft.com/en-us/download/details.aspx?id=14347
Allen Chen [MSFT]
MSDN Community Support | Feedback to us
- 已编辑 Allen Chen - MSFT 2012年11月26日 3:13
- 已建议为答案 Decker Dong - MSFT 2012年11月26日 8:47
- 已标记为答案 Decker Dong - MSFT 2012年11月28日 2:32
2012年11月26日 3:09