ASP.NET 身份 cookie 能否向后兼容表单身份验证?

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

我有一些现有的 ASP.NET MVC Web 应用程序,它们都使用 ASP.NET 成员资格和表单身份验证,并且 使用 OWIN,但我想将在 .NET Core 1.1 中使用 IdentityServer4 进行身份验证开发的新应用程序。我有一个使用自定义用户存储实现的 IdentityServer,因此来自旧 ASP.NET 成员数据库的现有用户可以登录到我的 IdentityServer(有关更多信息,请参阅 Whosebug 问题),但是由创建的身份验证 cookie ASP.NET 使用表单身份验证的旧应用无法识别身份。

我希望使用 ASP.NET Identity 在较旧的 Forms Authentication 应用程序和较新的应用程序之间进行单点登录,最好对较旧的应用程序进行尽可能少的更改。有没有办法让 ASP.NET Identity 生成 Forms Authentication 可以理解的身份验证 cookie?

我认为在这两种情况下,cookie 的内容都是经过序列化和加密的 ClaimsPrincipal 所以我的最大绊脚石似乎是同时获取 Forms Authentication 应用程序和 ASP.NET Identity 应用程序关于 encrypting/decrypting cookie 在同一页面上。由于 Forms Authentication 使用 web.config 文件中的 <machineKey> 元素加密 cookie,而 .NET Core 中的 ASP.NET Identity 使用 DPAPI,因此我必须弄清楚如何弥合这一差距。也许是这样的?

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

但我不知道 Protect()Unprotect() 方法的主体应该是什么。

This discussion 我在 GitHub 上与几个 ASP.NET Identity 和 IdentityServer 开发人员一起工作真的很有帮助。对于我关于在 Forms Authentication 和 ASP.NET Identity 之间共享 cookie 的问题,简短的回答是“你疯了!”幸运的是,还有一些替代方案。

Brock Allen 向我指出 IdentityServer's GitHub repo for client examples. For me, I think the MvcFormPostClient example 可以解决问题。在没有 OWIN 或 ASP.NET Identity 的旧 MVC 应用程序中实现 OpenID Connect 实际上并不难。