您好,欢迎访问三七文档
[]SSOSingleSign-Onforeveryone-2002-3443241855722002……[]SSOSingleSign-Onforeveryone前段时间为我们的系统做SSO(单点登录)参考了很多资料,其中包括博客园二级域名的登录.翻译本文是由于作者的一句话:思想都是一样的,只不过实现起来需要创造性思维.SingleSign-On(SSO)是近来的热门话题.很多和我交往的客户中都有不止一个运行在.Net框架中的Web应用程序或者若干子域名.而他们甚至希望在不同的域名中也可以只登陆一次就可以畅游所有站点.今天我们关注的是如何在各种不同的应用场景中实现SSO.我们由简到繁,逐一攻破.1.虚拟目录的主应用和子应用间实现SSO2.使用不同验证机制实现SSO(usernamemapping)3.同一域名中,子域名下的应用程序间实现SSO4.运行在不同版本.NET下的应用程序间实现SSO5.两个不同域名下的Web应用程序间实现SSO6.混合身份验证方式模式(FormsandWindows)下实现SSO1.虚拟目录的主应用和子应用之间实现SSO.NetWeb-FooBar,BarFoo().Forms.FormsApplication_AuthenticateRequest,FormsAuthentication.RedirectFromLoginPage..Asp.netcookie.RedirectFromLoginPageCALENDER20081028293012345678910111213141516171819202122232425262728293031123456782002......[2008-10-219:37:27][]SSOSingleSign-Onforeveryone-2002-FormsAuthenticationTicketcookie,cookie.Web.configcookie:authenticationmode=Formsformsname=.FooAuthprotection=Alltimeout=60loginUrl=login.aspx//authenticationauthenticationmode=Formsformsname=.BarAuthprotection=Alltimeout=60loginUrl=login.aspx//authentication比较重要的两个属性是name和protection.按照下面的配置就可以让Foo和Bar两个程序在同样的保护级别下读写Cookie,这就实现了SSO的效果:authenticationmode=Formsformsname=.SSOAuthprotection=Alltimeout=60loginUrl=login.aspx//authentication当protection属性设置为All,通过Hash值进行加密和验证数据都存放在Cookie中.默认的验证和加密使用的Key都存储在machine.config文件,我们可以在应用程序的Web.Config文件覆盖这些值.默认值如下:machineKeyvalidationKey=AutoGenerate,IsolateAppsdecryptionKey=AutoGenerate,IsolateAppsvalidation=SHA1/IsolateApps表示为每个应用程序生成不同的Key.我们不能使用这个.为了能在多个应用程序中使用相同的Key来加密解密cookie,我们可以移除IsolateApps选项或者更好的方法是在所有需要实现SSO的应用程序的Web.Config中设置一个具体的Key值:machineKeyvalidationKey=F9D1A2D3E1D3E2F7B3D9F90FF3965ABDAC304902decryptionKey=F9D1A2D3E1D3E2F7B3D9F90FF3965ABDAC304902F8D923ACvalidation=SHA1/如果你使用同样的存储方式,实现SSO只是改动一下Web.config而已.2.使用不同认证机制实现SSO(usernamemapping)要是FOO站点使用database来做认证,Bar站点使用MembershipAPI或者其它方式做认证呢?这种情景中FOO站点创建的cookie对Bar站点毫无用处,因为cookie中的用户名对Bar没有什么意义.cookie,Barcookie..FooJohnDoeBarjohnd.Foo:FormsAuthenticationTicketfat=newFormsAuthenticationTicket(1,johnd,DateTime.Now,DateTime.Now.AddYears(1),true,);HttpCookiecookie=newHttpCookie(.BarAuth);cookie.Value=FormsAuthentication.Encrypt(fat);MSN/Skype/Gtalk●(40)●●(201)■Ajax&JavaScript(23)(rss)■-(23)(rss)■-(29)(rss)■-(117)(rss)■(9)(rss)(179)■.Net(52)(rss)[2008-10-219:37:27][]SSOSingleSign-Onforeveryone-2002-cookie.Expires=fat.Expiration;HttpContext.Current.Response.Cookies.Add(cookie);FormsAuthentication.RedirectFromLoginPage(JohnDoe);为了演示用户名硬编码了.这个代码片段为Bar站点创建了令牌FormsAuthenticationTicket,这时令牌里的用户名在Bar站点的上下文中就是有意义的了.这时再调用RedirectFromLoginPage创建正确的认证cookie.上面的例子你统一了了Forms认证的cookie名字,而这里你要确保他们不同--因为我们不需要两个站点共享相同的cookie:authenticationmode=Formsformsname=.FooAuthprotection=Alltimeout=60loginUrl=login.aspxslidingExpiration=true//authenticationauthenticationmode=Formsformsname=.BarAuthprotection=Alltimeout=60loginUrl=login.aspxslidingExpiration=true//authentication现在当用户在Foo站点登录,他就会被映射到到Bar站点的用户并同时创建了Foo和Bar两个站点的认证令牌.如果你想在Bar站点登录在Foo站点通行,那么代码就会是这样:FormsAuthenticationTicketfat=newFormsAuthenticationTicket(1,JohnDoe,DateTime.Now,DateTime.Now.AddYears(1),true,);HttpCookiecookie=newHttpCookie(.FooAuth);cookie.Value=FormsAuthentication.Encrypt(fat);cookie.Expires=fat.Expiration;HttpContext.Current.Response.Cookies.Add(cookie);FormsAuthentication.RedirectFromLoginPage(johnd);同样要保证两个站点的Web.config的machineKey配置节有相同的加密和解密的Key!3.同一域名中,各子域名下应用程序间实现SSO要是这样的情况又将如何:FooBar两个站点运行在不同的域名下:上面的代码又不起作用了:因为cookie会存储在不同的文件中,各自的cookie对其它网站不可见.为了能让它起作用我们需要创建域级cookie,因为域级cookie对子域名都是可见的!这里我们也不能再使用RedirectFromLoginPage方法了,因为它不能灵活的创建域级cookie我们需要手工完成这个过程!FormsAuthenticationTicketfat=newFormsAuthenticationTicket(1,johnd,DateTime.Now,DateTime.Now.AddYears(1),true,);HttpCookiecookie=newHttpCookie(.BarAuth);cookie.Value=FormsAuthentication.Encrypt(fat);cookie.Expires=fat.Expiration;■Ajax&JavaScript(84)(rss)■ASP.NET(12)(rss)■Life(8)(rss)■NHibernate(23)(rss)●-612200●-30●1.re:,Not?●“”“”●--xiao_p●2.re:,Not?●●--●3.re:,Not?●!=CMMI●--●4.re:,Not?●●--jannock●5.re:,Not?●●--hahahehe●6.re:,Not?●●--GOOD●7.re:NHibernate[2008-10-219:37:27][]SSOSingleSign-Onforeveryone-2002-cookie.Domain=.foo.com;HttpContext.Current.Response.Cookies.Add(cookie);FormsAuthenticationTicketfat=newFormsAuthenticationTicket(1,JohnDoe,DateTime.Now,DateTime.Now.AddYears(1),true,);HttpCookiecookie=newHttpCookie(.FooAuth);cookie.Value=FormsAuthentication.Encrypt(fat);cookie.Expires=fat.Expiration;cookie.Domain=.foo.com;HttpContext.Current.Response.Cookies.Add(cookie);注意cookie.Domain=.foo.com;注意这一行.这里明确指定了cookie的域名为.foo.com,这样我们就保证了cookie对以及其它子域名都是可见的.(译者注:cookie的域名匹配规则是从右到左).你可以通过设置Bar站点的认证cookie的域名为bar.foo.com.这样对于其它子域名的站点它的cookie也是不可见的,这样安全了.注意RFC2109要求cookie前面有两个周期所以我们添加了一个过期时间.(cookie值实际上是一个字符串,各参数用逗号隔开).再次提醒,这里还是需要统一一下各个站点的Web.config的machineKey配置节
本文标题:[译]SSO解决方案大全 Single Sign-On for everyone - 回头再说 坚强
链接地址:https://www.777doc.com/doc-3494746 .html