身份验证方案无法识别共享的会话cookie [英] Shared session cookie is not being recognised by authentication scheme

查看:69
本文介绍了身份验证方案无法识别共享的会话cookie的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是来自上一篇文章的后续内容最初是一个普遍的问题,现在更具体了.

This follows on from a previous post which started as a general issue and is now more specific.

简而言之,我一直在遵循指导(例如来自Barry Dorrans ),允许我与新的dotnet核心应用共享由旧式ASP.NET Web应用发布的身份验证cookie.在同一个域上运行.

In short, I've been following guidance (such as this from Microsoft, this from Scott Hanselman, and this from Barry Dorrans) to allow me to share the authentication cookie issued by a legacy ASP.NET web app with a new dotnet core app running on the same domain.

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

I'm confident that I'm using the recommended Microsoft.Owin.Security.Interop library correctly. On that side (the old ASP.NET app), the CookieAuthenticationOptions are configured with AuthenticationType and CookieName both set to the same value - SiteIdentity. This same value is also used in the interop data protector setup:

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核心应用程序.

I log in using this app, confirm I have a cookie named SiteIdentity then switch to a new dotnet core app running on the same domain.

在那里,无需添加身份验证中间件,我可以确认可以取消保护和反序列化cookie.我是通过在启动中设置数据保护以匹配其他应用程序来实现的:

There, without adding authentication middleware I can confirm that I can unprotect and deserialize the cookie. I do this by setting up data protection in Startup to match the other app:

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:

Then in my controller I can use a data protector to manually unprotect the 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 确实引用了索赔主体,该索赔主体代表了我在其他应用程序上登录的帐户.

I can confirm that ticket.Principal does indeed reference a claims principal representing the account which I signed in with on the other app.

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

However, I've found it impossible to wire up the cookie authentication middleware to properly protect my endpoints using this cookie. This is what I've added to Startup, after the data protection code above:

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身份验证类型匹配),该cookie期望cookie也称为"SiteIdentity".其中将包含提供的数据保护器可以解释的受保护数据.

By my understanding this is telling the middleware that I have an authentication scheme named "SiteIdentity" (the advice is that authentication scheme must match the ASP.NET authentication type) which expects a cookie also called "SiteIdentity" which will contain protected data that the supplied data protector can interpret.

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

But when I add the attribute [Authorize(AuthenticationSchemes = "SiteIdentity")] to my controller I'm kicked away to a login page.

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

I can't understand what I'm doing wrong. As I've shown, I can confirm that it is indeed possible to use this data protector and ticket format to interpret the authentication cookie, so I guess I must have something wrong in this middleware wiring, but I'm not sure what.

推荐答案

请忽略.事实证明,我的代码实际上是正确的.我一直在研究该解决方案很长时间,以至于我用来测试的cookie值所代表的会话已经过期.万一代码使任何试图实现相同目标的人受益,将在这里留下这个问题.

Please ignore. It turns out that my code is actually correct. I had been working on this solution for long enough that the session represented by the cookie value I was using to test had expireed. Will leave this question here in case the code benefits anyone trying to achieve the same.

这篇关于身份验证方案无法识别共享的会话cookie的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆