5
Hintergrund

Ich entwickle eine iterative Migration von einer älteren ASP.NET-Formularanwendung zu einer MVC 4-Anwendung.Wie bekomme ich den aktuellen Kontext oder die Benutzeridentität aus einer separaten .NET-Anwendung?

Diese Migration erfolgt schrittweise, Abschnitt für Abschnitt, sodass sowohl die ältere als auch die neue MVC-Anwendung gleichzeitig ausgeführt werden müssen. Für einige Abschnitte wird der Benutzer zu der neuen Anwendung geleitet, und für Abschnitte, die noch migriert werden müssen, wird der Benutzer zurück zu der Legacy-Anwendung geleitet (oder verbleibt dort).

Auf dem Server werden die Anwendungen wie folgt strukturiert:

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

So ein Aufruf an foo Seite auf Legacy-/foo.aspx ist und auf V2 /V2/foo es ist.

Alles ist in C#, aber bitte beachten Sie, dass die Legacy-App auf .NET 2.0 läuft und die V2-App auf .NET 4.5 läuft. Ich bin mir nicht sicher, ob das wichtig ist, aber ich denke, es wäre wichtig zu beachten.

Problem

I nicht erfolgreich den Benutzer/Authentifizierungszustand zwischen Anwendungen gemeinsam nutzen können. Offensichtlich muss ich, wenn sich der Benutzer an der Legacy-App anmeldet, den Auth-Cookie (oder ähnliche Aktionen) in der V2-App abholen, wenn eine V2-Seite aufgerufen wird, damit der Benutzer nicht erneut zur Anmeldung aufgefordert wird.

Was ich versucht habe

ich habe eingestellt identisch authentication und machinekey Elemente in beiden web.config-Dateien:

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

ich habe versucht, diesen Code in der Global.asax der V2 Anwendung:

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

Aber ich habe keine Ahnung, ob es funktioniert, weil die Legacy-App nicht in der gleichen Lösung wie meine V2-App ist und ich daher keine Möglichkeit habe, mich über die V2-App einzuloggen Legacy-App und simulieren die tatsächliche Benutzererfahrung des Hopping zwischen Legacy und V2.

Ich habe auch gerade versucht, diese zu meinen HomeController in der Hoffnung, dass die gleiche Maschine Schlüssel wäre für mich etwas Magie arbeiten:

ViewBag.UserName = User.Identity.Name; 

Offensichtlich ich dann ViewBag.UserName binden an ein HTML-Element in der Ansicht, aber das scheint auch nicht zu funktionieren.

Antwort

1

Welche Domains/Subdomains verwenden Sie für die beiden Apps? Cookies werden nicht zwischen Domains oder sogar Subdomains geteilt (es sei denn, der Cookie ist auf der Wildcard-Domain gesetzt, d. H. * .mydomain.com).

Zum Beispiel, wenn die V1 App auf v1.somedomain.com ist und der Cookie auf v1.somedomain.com gesetzt ist. Dann wird V2, bei v2.somedomain.com, nicht sehen. Wenn Sie jedoch den Cookie auf * .somedomain.com setzen, sehen beide Apps den Cookie.

Wenn V1 jedoch auf v1domain.com und V2 auf v2domain.com steht, haben Sie kein Glück. Es gibt keine Möglichkeit, den Cookie zu teilen.

+0

Dank. Ich hatte tatsächlich gehofft, dieses Szenario genau zu vermeiden, indem ich die V2-App als Unterordner der übergeordneten Domäne und nicht als Subdomain davon konfiguriere. Also, da es in einem Unterordner ist, würde Ihre Logik oben immer noch gelten? Vielen Dank! –

+0

Solange sie die Domäne teilen, auf der der Cookie gesetzt ist, sollten beide in der Lage sein, sie zu sehen. –

2

Die Signatur- und Verschlüsselungsalgorithmen für Formulare Auth wechselte zwischen .NET 2.0 und 4.0; so in Ihrem 4.0 Config

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

Hinweis versuchen, dass Sie jetzt eine persistente Auth Methode Schlagen Sie Ihre WebAPI Endpunkte haben Sie anfällig für CSRF sind und Sie werden gegen sie schützen müssen. Mike Wasson hat eine walkthrough auf asp.net

+0

Danke dafür, aber auch nachdem ich diese Elemente zur web.config hinzugefügt habe, kann ich immer noch auf keinen Benutzerkontext zugreifen. Können Sie ein Beispiel veröffentlichen, wie ich den Benutzernamen des angemeldeten Benutzers abrufen würde? Ich habe 'User.Identity.Name' versucht, aber das schlägt fehl. Fehle ich etwas? Vielen Dank! –

+0

Sie sollten nichts Magisches tun müssen; der auth cookie * sollte * jetzt über beide Apps funktionieren. Wenn Sie Ihre V2-App für forms auth konfigurieren, ohne eine benutzerdefinierte AuthenticateRequest, sollten Sie die Cookies gut teilen. Lassen Sie uns die webapi-Bits jetzt einfach ignorieren und konzentrieren Sie sich auf die Konfiguration einer v2- und v4-App für die Freigabe. Ich würde vorschlagen, ein Skelett aufzustellen, formiert zuerst hallo User. – blowdart