代码之家  ›  专栏  ›  技术社区  ›  Community wiki

如何在应用程序域之间传递经过身份验证的会话

  •  9
  • Community wiki  · 技术社区  · 3 年前

    假设你有网站www.xyz.com和www.abc.com。

    假设用户访问www.abc.com,并通过普通的ASP.NET会员资格提供商进行身份验证。

    然后,从该网站,它们被发送到(重定向、链接、任何有效的)网站www.xyz.com,网站www.abc.com的目的是将该用户作为isAuthenticated的状态传递给另一个网站,这样网站www.xyz就不会再次要求该用户的凭据。

    这需要什么才能奏效?不过,我对此有一些限制,用户数据库是完全独立的,它不是一个组织内部的,从各个方面来看,这就像从stackoverflow.com传递到经过身份验证的谷歌,本质上是独立的。一个相关文章的链接就足够了。

    8 回复  |  直到 9 年前
        1
  •  5
  •   craigmoliver    9 年前

    尝试使用FormAuthentication,方法是将web.config身份验证部分设置为:

    <authentication mode="Forms">
      <forms name=".ASPXAUTH" requireSSL="true" 
          protection="All" 
          enableCrossAppRedirects="true" />
    </authentication>
    

    生成机器密钥。示例: Easiest way to generate MachineKey – Tips and tricks: ASP.NET, IIS ...

    当发布到其他应用程序时,身份验证票证将作为隐藏字段传递。当从第一个应用程序读取帖子时,第二个应用程序将读取加密的票证并对用户进行身份验证。下面是一个传递字段的页面示例:

    .aspx:

    <form id="form1" runat="server">
      <div>
        <p><asp:Button ID="btnTransfer" runat="server" Text="Go" PostBackUrl="http://otherapp/" /></p>
        <input id="hdnStreetCred" runat="server" type="hidden" />
      </div>
    </form>
    

    代码隐藏:

    protected void Page_Load(object sender, EventArgs e)
    {
        FormsIdentity cIdentity = Page.User.Identity as FormsIdentity;
        if (cIdentity != null)
        {
            this.hdnStreetCred.ID = FormsAuthentication.FormsCookieName;
            this.hdnStreetCred.Value = FormsAuthentication.Encrypt(((FormsIdentity)User.Identity).Ticket);
        }
    }
    

    另请参阅本章第5章中的跨应用程序表单验证部分 book 来自弗罗克斯。除了提供自制的SSO解决方案外,它还推荐类似上面的答案。

        2
  •  2
  •   Adam Pope    18 年前

    如果您使用的是内置的成员系统,则可以通过在每个web.config中使用类似的方法,使用表单身份验证进行跨子域身份验证。

    <authentication mode="Forms">
        <forms name=".ASPXAUTH" loginUrl="~/Login.aspx" path="/" 
                      protection="All" 
                      domain="datasharp.co.uk" 
                      enableCrossAppRedirects="true" />
    
    </authentication>
    

    确保所有web.config中的名称、路径、保护和域都相同。如果站点位于不同的计算机上,则还需要确保machineKey以及验证和加密密钥相同。

        3
  •  1
  •   public static    18 年前

    如果将用户会话存储在数据库中,则可以简单地检查会话表中是否存在Guid,如果存在,则表明用户已在其他域上进行了身份验证。要做到这一点,当您将用户重定向到其他网站时,必须在URL中包含会话guid。

        4
  •  0
  •   Marc Gear    18 年前

    不确定你会把什么用在.NET上,但通常我会用 memcached LAMP堆栈中。

        5
  •  0
  •   Matej    18 年前

    分辨率取决于应用程序的类型及其运行环境。例如,在带有NT域的intranet上,您可以使用NTLM将windows凭据直接传递到intranet外围的服务器,而无需复制会话。

    如何做到这一点的方法通常命名为 单点登录 (参见 Wikipedia )。

        6
  •  0
  •   Markc    18 年前

    这个问题有多种方法,被称为“跨域单点登录”。如果你正在寻找一个开源解决方案,Matej提到的维基百科文章会特别有帮助——然而,在windows环境中,我认为你最好采用以下两种方法之一:

    1. 购买商业SSO产品(如SiteMinder或PingIdentity)
    2. 使用MicroSoft的跨域SSO解决方案,称为 ADFS -Active Direccury Federation Services。(联合是指协调多个域的行为)

    我用过SiteMinder,效果很好,但很贵。如果你在一个全MicroSoft的环境中,我认为ADFS是你最好的选择 ADFS whitepaper 。

        7
  •  0
  •   Christian D    18 年前

    我会使用类似CAS的内容:

    [1] : http://www.ja-sig.org/products/cas/ CAS

    这是一个已解决的问题,不建议您自己滚动。

        8
  •  -1
  •   Toby Mills    18 年前

    或者,如果你想滚动自己的网站,而有问题的网站不在同一服务器上,或者无法访问共享数据库(在这种情况下,请参阅上面的回复),那么你可以放置 web beacon 在每个站点上,这些站点将引用回另一个站点。

    在站点a上放置一个单像素图像(网络信标),该图像将通过用户ID(加密并加盖时间戳)调用站点B。然后,这将在站点B上为用户创建一个新的用户会话,该会话将被设置为已登录。然后,当用户访问站点B时,他们将已经登录。

    为了尽量减少通话,您只能将网络信标放在主页和/或登录确认页面。我过去曾成功地使用它在合作伙伴网站之间传递信息。

    推荐文章