Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the current context or user identity from a separate .NET application?

Background

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

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.

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.

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.

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.

What I have tried

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

  <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:

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.

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

 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.

like image 863
Matt Cashatt Avatar asked Mar 20 '13 14:03

Matt Cashatt


2 Answers

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

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

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

like image 151
Ryan Loken Avatar answered Sep 23 '22 17:09

Ryan Loken


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

<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

like image 29
blowdart Avatar answered Sep 25 '22 17:09

blowdart