代码之家  ›  专栏  ›  技术社区  ›  Matt Cashatt

如何从单独的.NET应用程序中获取当前上下文或用户标识?

  •  5
  • Matt Cashatt  · 技术社区  · 11 年前

    出身背景

    我正在开发一个从传统的ASP.NET表单应用程序到MVC 4应用程序的迭代迁移。

    这种迁移是分阶段进行的,每次一个部分,因此有必要同时运行遗留的MVC应用程序和新的MVC应用软件。对于某些部分,用户会被引导到新的应用程序,而对于尚未迁移的部分,用户则会被引导回(或留在)旧的应用程序。

    在服务器上,应用程序的结构如下:

    LEGACY (.NET 2.0 forms app)--
                                |--Api (new MVC 4 WebAPI)
                                |--V2 (new MVC 4)
    

    所以打电话给 foo 关于遗留问题的页面是 /foo.aspx 在V2上 /V2/foo .

    一切都在C#中,但请注意 旧版应用程序在.NET 2.0上运行,V2应用程序在.NET4.5上运行 。我不确定这是否重要,但我认为值得注意。

    问题

    我无法在应用程序之间成功共享用户/身份验证状态。显然,如果用户在旧版应用程序上登录,当调用V2页面时,我需要在V2应用程序上获取他们的auth cookie(或采取类似操作),这样用户就不会再次被提示登录。

    我尝试过的

    我设置了相同的 authentication machinekey 两个web.config文件中的元素:

      <authentication mode="Forms">
          <forms cookieless="UseCookies" defaultUrl="~/someUrl" loginUrl="/" path="/" protection="All" timeout="240"  enableCrossAppRedirects ="true" domain="someDomain.com" requireSSL="false"  />
      </authentication>
      <machineKey validationKey="DE78CF63226. . .788658D142AB881" decryptionKey="0B97E8BA4C4EB4B4C524. . .54E4622E14168D2D5C84461FA2" validation="SHA1" decryption="AES" />
    

    我在V2应用程序的Global.asax中尝试过以下代码:

    protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
        string cookieName = FormsAuthentication.FormsCookieName;
        HttpCookie authCookie = Context.Request.Cookies[cookieName];
    
        if (authCookie == null)
        {
            return;
        }
        FormsAuthenticationTicket authTicket = null;
        try
        {
            authTicket = FormsAuthentication.Decrypt(authCookie.Value);
        }
        catch
        {
            return;
        }
        if (authTicket == null)
        {
            return;
        }
        string[] roles = authTicket.UserData.Split(new char[] { '|' });
        var id = new FormsIdentity(authTicket);
        var principal = new GenericPrincipal(id, roles);
    
        //Thread.CurrentPrincipal = principal;
    
        Context.User = principal;
    }
    

    但我不知道它是否有效 因为遗留应用程序与我的V2应用程序不在同一解决方案中,因此当我调试V2应用程序时,我无法通过遗留应用程序登录并模拟在遗留应用程序和V2之间跳跃的实际用户体验。

    我也刚刚尝试将此添加到我的 HomeController 希望相同的机器钥匙能给我带来一些魔力:

     ViewBag.UserName = User.Identity.Name;
    

    很明显,我会绑定 ViewBag.UserName 到视图中的html元素,但这似乎也不起作用。

    3 回复  |  直到 4 年前
        1
  •  2
  •   Ryan Loken    11 年前

    在父应用程序上设置machineKey compatibility Mode=“Framework20SP2”。

    .net 4.5无法从4.0(或更低版本)读取身份验证令牌

    http://technet.microsoft.com/en-us/subscriptions/index/system.web.configuration.machinekeycompatibilitymode

    http://blogs.msdn.com/b/webdev/archive/2012/10/23/cryptographic-improvements-in-asp-net-4-5-pt-2.aspx

        2
  •  2
  •   blowdart    11 年前

    表单身份验证的签名和加密算法在.NET 2.0和4.0之间切换;所以在4.0配置中尝试

    <appSettings>
        <add key="aspnet:UseLegacyFormsAuthenticationTicketCompatibility" value="true" />
        <add key="aspnet:UseLegacyEncryption" value="true" />
        <add key="aspnet:UseLegacyMachineKeyEncryption" value="true" />
    </appSettings>
    

    请注意,现在您有一个持久的身份验证方法攻击您的webapi端点,您很容易受到CSRF的攻击,您需要对此进行保护 walkthrough 在asp.net上

        3
  •  1
  •   Chris Pratt    11 年前

    您为这两个应用程序使用的域/子域是什么?cookie不会在域甚至子域之间共享(除非cookie设置在通配符域上,即*.mydomain.com)。

    例如,如果V1应用程序位于V1.somedomain.com,而cookie设置在V1.somedomain.com。那么V2位于V2.somedomain.com,将 看到了。但是,如果你在*.somedomain.com上设置cookie,那么 二者都 应用程序将看到cookie。

    然而,如果V1在v1domain.com上,V2在v2domain.com上的话,那你就倒霉了。没有办法分享饼干。