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

时间:2013-03-20 14:39:45

标签: asp.net asp.net-mvc forms-authentication membership-provider

背景

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

此迁移分阶段进行,一次一个部分,因此有必要同时运行旧版和新版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应用程序在.NET 4.5上运行。我不确定这是否重要,但认为重要的是要注意。

问题

我无法在应用程序之间成功共享用户/身份验证状态。显然,如果用户登录遗留应用程序,我需要在调用V2页面时在V2应用程序上获取其auth cookie(或采取类似操作),以便再次提示用户无法登录。 / p>

我尝试了什么

我在两个web.config文件中都设置了相同的authenticationmachinekey元素:

  <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应用程序时,我没有办法通过Legacy应用程序登录并模拟在legacy和V2之间跳跃的实际用户体验。

我也尝试将此添加到我的HomeController,希望相同的机器键对我来说有点神奇:

 ViewBag.UserName = User.Identity.Name;

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

3 个答案:

答案 0 :(得分:2)

表单身份验证的签名和加密算法在.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的攻击,并且您需要防范它。 Mike Wasson在asp.net上有一个walkthrough

答案 1 :(得分:2)

答案 2 :(得分:1)

您为这两个应用使用的域名/子域名是什么? 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上,那么你运气不好。没有办法分享cookie。