身份验证方案无法识别共享会话 cookie

时间:2021-04-01 12:48:53

标签: c# asp.net asp.net-core authentication cookies

这是继 previous post 开始的一般问题,现在更加具体。

简而言之,我一直在遵循指导(例如 this from Microsoftthis from Scott Hanselmanthis from Barry Dorrans)以允许我共享由旧版 ASP.NET 网站发布的身份验证 cookie具有在同一域中运行的新 dotnet 核心应用的应用。

我确信我正确使用了推荐的 Microsoft.Owin.Security.Interop 库。在这方面(旧的 ASP.NET 应用程序),CookieAuthenticationOptions 配置为 AuthenticationTypeCookieName 都设置为相同的值 - SiteIdentity。互操作数据保护器设置中也使用了相同的值:

var appName = "SiteIdentity";

var encryptionSettings = new AuthenticatedEncryptorConfiguration
{
    EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
    ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
};

var interopProvider = DataProtectionProvider.Create(
    new DirectoryInfo(keyRingSharePath),
    builder =>
    {
        builder.SetApplicationName(appName);
        builder.SetDefaultKeyLifetime(TimeSpan.FromDays(365 * 20));
        builder.UseCryptographicAlgorithms(encryptionSettings);

        if (!generateNewKey)
        {
            builder.DisableAutomaticKeyGeneration();
        }
    });

ShimmedDataProtector = new DataProtectorShim(
    interopProvider.CreateProtector(
        "Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware",
        appName,
        "v2"));

我使用此应用登录,确认我有一个名为 SiteIdentity 的 cookie,然后切换到在同一域上运行的新 dotnet 核心应用。

在那里,无需添加身份验证中间件,我就可以确认我可以取消保护和反序列化 cookie。为此,我在 Startup 中设置数据保护以匹配其他应用:

var appName = "SiteIdentity";

services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(keyRingSharePath))
    .SetDefaultKeyLifetime(TimeSpan.FromDays(365 * 20))
    .DisableAutomaticKeyGeneration()
    .UseCryptographicAlgorithms(new AuthenticatedEncryptorConfiguration()
    {
        EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
        ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
    })
    .SetApplicationName(appName);

然后在我的控制器中,我可以使用数据保护程序来手动取消对 cookie 的保护:

var appName = "SiteIdentity";

var protector = _dataProtectionProvider.CreateProtector(
    "Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware",
    appName,
    "v2");

var cookieValue = Request.Cookies[appName];
var format = new TicketDataFormat(protector);
var ticket = format.Unprotect(cookieValue);

我可以确认 ticket.Principal 确实引用了代表我在其他应用上登录的帐户的声明主体。

但是,我发现无法连接 cookie 身份验证中间件以使用此 cookie 正确保护我的端点。这是我在上面的数据保护代码之后添加到 Startup 的内容:

var protectionProvider = services.BuildServiceProvider().GetService<IDataProtectionProvider>();

var dataProtector = protectionProvider.CreateProtector(
    "Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware",
    appName,
    "v2");

services
    .AddAuthentication(appName)
    .AddCookie(appName, options =>
    {
        options.TicketDataFormat = new TicketDataFormat(dataProtector);
        options.Cookie.Name = appName;
    });

据我所知,这是告诉中间件我有一个名为“SiteIdentity”的身份验证方案(建议身份验证方案必须与 ASP.NET 身份验证类型匹配),它需要一个也称为“SiteIdentity”的 cookie,其中包含受保护的提供的数据保护程序可以解释的数据。

但是当我将属性 [Authorize(AuthenticationSchemes = "SiteIdentity")] 添加到我的控制器时,我被踢到了登录页面。

我不明白我做错了什么。正如我所展示的,我可以确认确实可以使用此数据保护器和票证格式来解释身份验证 cookie,所以我想我在此中间件接线中一定有问题,但我不确定是什么。< /p>

1 个答案:

答案 0 :(得分:0)

请无视。事实证明,我的代码实际上是正确的。我已经在这个解决方案上工作了很长时间,以至于我用来测试的 cookie 值表示的会话已经过期。如果代码有利于任何试图实现相同目标的人,将把这个问题留在这里。