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

时间:2022-08-13 07:30:11

Background

I am developing an iterative migration from a legacy ASP.NET forms app to an MVC 4 app.

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

This migration is happening in stages, one section at a time, so it is necessary to run both the legacy and the new MVC application simultaneously. For some sections, the user is directed to the new application, and for sections that have yet to be migrated, the user is directed back to (or remains on) the legacy application.

此迁移分阶段进行,一次一个部分,因此必须同时运行旧版和新MVC应用程序。对于某些部分,用户将被定向到新应用程序,对于尚未迁移的部分,用户将被定向回(或保留在)旧应用程序上。

On the server, the applications are structured like this:

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

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

So a call to foo page on legacy is /foo.aspx and on V2 it's /V2/foo.

因此,对遗留的foo页面的调用是/foo.aspx,而在V2它是/ V2 / foo。

Everything is in C#, but please note that the legacy app is running on .NET 2.0 and the V2 app is running on .NET 4.5. I am not sure if this matters, but thought it would be important to note.

一切都在C#中,但请注意遗留应用程序在.NET 2.0上运行,V2应用程序在.NET 4.5上运行。我不确定这是否重要,但认为重要的是要注意。

Problem

I can not successfully share the user/authentication state between applications. Obviously, if the user logged in on the legacy app, I need to grab their auth cookie (or take similar action) on the V2 app when a V2 page is called up so that the user does not get prompted again to log in.

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

What I have tried

I have set identical authentication and machinekey elements in both web.config files:

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

  <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" />

I have tried this code in the Global.asax of the V2 application:

我在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;
}

But I have no idea whether or not it works because the legacy app is not in the same solution as my V2 app and therefore when I debug the V2 app, I don't have a way to log in via the Legacy app and simulate the actual user experience of hopping between legacy and V2.

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

I have also just tried adding this to my HomeController in hopes that the identical machine keys would work some magic for me:

我也尝试将它添加到我的HomeController,希望相同的机器键对我有用:

 ViewBag.UserName = User.Identity.Name;

Obviously, I then bind ViewBag.UserName to an html element in the view, but this doesn't seem to work either.

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

3 个解决方案

#1


2  

Set the machineKey compatibilityMode="Framework20SP2" on the parent app.

在父应用上设置machineKey compatibilityMode =“Framework20SP2”。

.net 4.5 can't read auth tokens from 4.0 (or below)

.net 4.5无法从4.0(或更低版本)读取auth令牌

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

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

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

#2


2  

The signing and encryption algorithms for forms auth switched between .NET 2.0 and 4.0; so in your 4.0 config try

表单身份验证的签名和加密算法在.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>

Note that now you have a persistent auth method hitting your webapi endpoints you are vulnerable to CSRF and you will need to protect against it. Mike Wasson has a walkthrough on asp.net

请注意,现在您有一个持久的身份验证方法命中您的webapi端点,您很容易受到CSRF的攻击,并且您需要防范它。 Mike Wasson在asp.net上进行了一次演练

#3


1  

What are the domains/subdomains you're using for the two apps? Cookies are not shared between domains or even subdomains (unless the cookie is set on the wildcard domain, i.e. *.mydomain.com).

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

For example, if the V1 app is at v1.somedomain.com and the cookie is set on v1.somedomain.com. Then V2, at v2.somedomain.com, will not see it. However, if you set the cookie on *.somedomain.com, then both apps will see the cookie.

例如,如果V1应用程序位于v1.somedomain.com,则cookie在v1.somedomain.com上设置。然后V2,在v2.somedomain.com,将看不到它。但是,如果您在* .somedomain.com上设置cookie,则两个应用都将看到cookie。

However, if V1 is on v1domain.com and V2 is on v2domain.com, you're out of luck. There's no way to share the cookie.

但是,如果V1在v1domain.com上,V2在v2domain.com上,那你就不走运了。没有办法分享cookie。

#1


2  

Set the machineKey compatibilityMode="Framework20SP2" on the parent app.

在父应用上设置machineKey compatibilityMode =“Framework20SP2”。

.net 4.5 can't read auth tokens from 4.0 (or below)

.net 4.5无法从4.0(或更低版本)读取auth令牌

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

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

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

#2


2  

The signing and encryption algorithms for forms auth switched between .NET 2.0 and 4.0; so in your 4.0 config try

表单身份验证的签名和加密算法在.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>

Note that now you have a persistent auth method hitting your webapi endpoints you are vulnerable to CSRF and you will need to protect against it. Mike Wasson has a walkthrough on asp.net

请注意,现在您有一个持久的身份验证方法命中您的webapi端点,您很容易受到CSRF的攻击,并且您需要防范它。 Mike Wasson在asp.net上进行了一次演练

#3


1  

What are the domains/subdomains you're using for the two apps? Cookies are not shared between domains or even subdomains (unless the cookie is set on the wildcard domain, i.e. *.mydomain.com).

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

For example, if the V1 app is at v1.somedomain.com and the cookie is set on v1.somedomain.com. Then V2, at v2.somedomain.com, will not see it. However, if you set the cookie on *.somedomain.com, then both apps will see the cookie.

例如,如果V1应用程序位于v1.somedomain.com,则cookie在v1.somedomain.com上设置。然后V2,在v2.somedomain.com,将看不到它。但是,如果您在* .somedomain.com上设置cookie,则两个应用都将看到cookie。

However, if V1 is on v1domain.com and V2 is on v2domain.com, you're out of luck. There's no way to share the cookie.

但是,如果V1在v1domain.com上,V2在v2domain.com上,那你就不走运了。没有办法分享cookie。