【问题标题】:Shared session cookie is not being recognised by authentication scheme身份验证方案无法识别共享会话 cookie
【发布时间】:2021-06-28 11:18:02
【问题描述】:

这是从 previous post 开始的,它最初是一个一般性问题,现在更加具体。

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

我确信我正确使用了推荐的 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,所以我想我的中间件接线肯定有问题,但我不确定是什么。

【问题讨论】:

  • "SiteIdentity""Site.Identity"?我看到你的appName 最初设置为SiteIdentity,但后来你在AuthorizeAttribute 中使用"Site.Identity"
  • 抱歉,打错了。我不想使用真正的价值来避免泄露内部信息。会更正。
  • 您手动测试的代码可能与身份验证中间件中的代码不等价,这里是从 cookie github.com/dotnet/aspnetcore/blob/… 读取票证的位置 - 您可能需要调试源代码(那里)才能走着瞧吧。其他人很难看出这里出了什么问题(当然,对此有深入了解的人可能会发现它)。
  • 原来我是个白痴。我正在测试的 cookie 代表一个过期的会话。启用跟踪后,我可以在控制台中看到此信息??????♂️

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


【解决方案1】:

请忽略。事实证明,我的代码实际上是正确的。我已经在这个解决方案上工作了足够长的时间,以至于我用来测试的 cookie 值所代表的会话已经过期。将在此处留下这个问题,以防代码使任何试图实现相同目标的人受益。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 2016-01-22
    • 1970-01-01
    • 2019-10-28
    • 1970-01-01
    • 2011-11-23
    • 2016-02-29
    相关资源
    最近更新 更多