Search code examples
c#asp.netcookiesasp.net-identityforms-authentication

Can ASP.NET Identity cookies be backwards compatible with Forms Authentication?


I have a number of existing ASP.NET MVC web application that all use ASP.NET Membership and Forms Authentication and not using OWIN, but I would like new apps to be developed in .NET Core 1.1 using IdentityServer4 for auth. I have an IdentityServer implemented with a custom user store so existing users from the old ASP.NET Membership database can log into my IdentityServer (see this StackOverflow question for more information about that), however the authentication cookie created by ASP.NET Identity isn't recognized by the older apps using Forms Authentication.

I'd like to have single sign-on between the older Forms Authentication apps and the newer apps using ASP.NET Identity, preferably with make as few changes as possible to the older apps. Is there a way to make ASP.NET Identity generate authentication cookies that Forms Authentication can understand?

I think in both cases, the contents of the cookie is a serialized and encrypted ClaimsPrincipal so it seems like my big stumbling block is getting both the Forms Authentication app and the ASP.NET Identity app to be on the same page with respect to encrypting/decrypting the cookie. Since Forms Authentication encrypts the cookie using the <machineKey> element in the web.config file and ASP.NET Identity in .NET Core uses DPAPI, I'll have to figure out how to bridge that gap. Maybe something like this?

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.Configure<IdentityOptions>(options =>
    {
        ...

        options.Cookies.ApplicationCookie.DataProtectionProvider = 
            new FormsAuthenticationDataProtector();

        ...
    });
}

FormsAuthenticationDataProtector.cs

public class FormsAuthenticationDataProtector : IDataProtector
{
    public IDataProtector CreateProtector(string purpose)
    {
        return this;
    }

    public byte[] Protect(byte[] plaintext)
    {
        // TODO: Mimic the Forms Authentication encryption algorithm.
    }

    public byte[] Unprotect(byte[] protectedData)
    {
        // TODO: Mimic the Forms Authentication decryption algorithm.
    }
}

But I have no idea what the bodies of the Protect() and Unprotect() methods should be.


Solution

  • This discussion I had with a couple of ASP.NET Identity and IdentityServer devs on GitHub was really helpful. The short answer to my question about sharing a cookie between Forms Authentication and ASP.NET Identity was "You're insane!" Fortunately, there are some alternatives.

    Brock Allen pointed me to IdentityServer's GitHub repo for client examples. For me, I think the MvcFormPostClient example is going to do the trick. It's actually not that hard to implement OpenID Connect in an older MVC app without OWIN or ASP.NET Identity.