单点登录在项目中的实现 转.

最近在做一个登录功能,纠结了好几天,一直在找一个能优雅的实现单点登录的功能。博客园有看到某人写了又臭又长的八股文式的文章,没看到有价值的东西。

其实单点登录最终要解决的是多个不同域名间共享cookie的问题。但是要在不同域名间共享cookie是一件很困难的事情,要在某个域名下面种cookie就必须访问该

域名。网上有很多方法,看到的有动态创建iframe实现,在iframe里面访问某个域名的页面种下cookie,该方法需要写一些js代码,写起来有点累,所以我最终

选择了用页面跳转来实现,想不到效果比我预期的好很多,浏览器几乎看不出来有跳转的痕迹。

详细介绍下流程:

1. 项目有3个不同的域名,login.susucms.com, suhow.com, sigcms.com。其中login.susucms.com/login.aspx是登录页面。实现的功能是通过login.susucms.com/login.aspx登录后能够实现在访问其他域名也可以保持登录状态。

2. 在suhow.com和sigcms.com下分别添加一个sso.aspx的页面。

3. 当用户在login.susucms.com/login.aspx页面点击登录,服务器端通过验证后生成一个token,接着服务器端Response.Redirect到suhow.com/sso.aspx,suhow.com/sso.aspx立即验证这个token是否合法,如果合法则Reponse一个包含登录信息的cookie,然后Response.Redirect到sigcms.com/sso.aspx,sigcms.com/sso.aspx也验证这个token是否合法,如果合法则Reponse一个包含登录信息的cookie,然后销毁token,Response.Redirect到登录后的后台。

整个流程最核心的其实就是跳转。没有其他的了。经过测试,服务器端响应非常快,几乎感觉不到任何跳转,所以再多跳转几个域名,我想是没有什么大问题的。

简单代码:

1. login.susucms.com/login.aspx

01if (IsLogin)
02{
03    var login = new CrossDomainLogin
04    {
05        Key = Guid.NewGuid().ToString(),
06        CreateTime = DateTime.Now
07    };
08    DataContext.CrossDomainLogins.InsertOnSubmit(login);
09    DataContext.SubmitChanges();
10  
11    WriteAuthenticationCookie();
12    Response.Redirect("http://suhow.com/sso.aspx?key=" + login.Key);
13}

2. suhow.com/sso.aspx

01var key = Request.QueryString["key"];
02var login = DataContext.CrossDomainLogins.FirstOrDefault(i => i.Key == key);
03if (login != null)
04{
05    // key will be expired in 3 minutes
06    if (DateTime.Now.Minute - login.DateTime.Minute > 3)
07    {
08        RemoveKey(login);   // delete key from database
09        Response.Redirect("http://login.susucms.com/login.aspx");
10    }
11    else
12    {
13        WriteAuthenticationCookie();
14        Response.Redirect("http://sigcms.com/sso.aspx?key=" + login.Key);
15    }
16}
17else
18{
19    // ....
20}

3. sigcms.com/sso.aspx

01var key = Request.QueryString["key"];
02var login = DataContext.CrossDomainLogins.FirstOrDefault(i => i.Key == key);
03if (login != null)
04{
05    // key will be expired in 3 minutes
06    if (DateTime.Now.Minute - login.DateTime.Minute > 3)
07    {
08        RemoveKey(login);   // delete key from database
09        Response.Redirect("http://login.susucms.com/login.aspx");
10    }
11    else
12    {
13        WriteAuthenticationCookie();
14        RemoveKey(login);   // delete key from database
15     Response.Redirect("http://login.susucms.com/admin/default.aspx");
16    }
17}
18else
19{
20    // ....
21}
============================================================================================================
2208516
  回复  引用  查看   
#1楼 2011-09-27 00:25 willerce       
可以用js的方式调用各个域名。
可以生成cookie。
跳转的方式在域名多的时候,问题就出来了,并且扩展性不好。
  回复  引用  查看   
#2楼 2011-09-27 08:27 豫风       
验证端用cache保存登录信息,其它站点使用session保存登录标志,其它站点每一个页面都继承一个基类(带验证功能的)。使用服务验证
  回复  引用  查看   
#3楼 2011-09-27 08:32 Hunt       
又臭又长的八股文,哈哈,了解
  回复  引用  查看   
#4楼 2011-09-27 08:53 allentranks       
为啥不用iframe?
还得一个一个跳转?
  回复  引用  查看   
#5楼 2011-09-27 08:56 鹤冲天       
跨应用程序进行 Forms 身份验证:ASP.NET 支持在分布式环境中(跨单个服务器上的多个应用程序或在网络场中)进行 Forms 身份验证...http://msdn.microsoft.com/zh-cn/library/eb0zx8fc.aspx
  回复  引用  查看   
#6楼 2011-09-27 09:03 HoYO       
看不出来你跳转 是因为你本机测试 速度当然块了 要是网速慢点的 你跳来跳去 用户就迷茫了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值