繁体   English   中英

与 .NET Core 应用程序共享 ASP.NET Owin Cookie,同时将密钥保存到 Azure 存储

[英]Share ASP.NET Owin Cookies with .NET Core Application whilst persisting keys to azure storage

我们有一个针对 ASP.Net Framework (4.7.2) 构建的 WebForms 应用程序,它使用 OWIN cookie 身份验证。 作为向 .Net Core 迁移的一部分,我们希望在 .Net Core (2.1) API 应用程序中使用 cookie。

WebForms 应用程序在 Azure 中运行,并利用DataProtectionStartup将机器密钥文件挂接到IServiceCollection ,以根据 Microsoft 文档使用Microsoft.AspNetCore.DataProtectionPersistKeysToAzureBlobStorage方法。

WebForms 数据DataProtectionStartup

    services.AddDataProtection()
        .PersistKeysToAzureBlobStorage(blockblob)
        .SetApplicationName("OurAppName");

.Net Core API Startup

    services.AddDataProtection()
        .PersistKeysToAzureBlobStorage(blockblob)
        .SetApplicationName("OurAppName");

两个应用程序都使用生成并存储在 blob 存储中的机器密钥愉快地运行。

微软有机制的文档是详细介绍了如何与人交流共享的机器密钥文件的OWIN饼干,使用DataProtectorShimMicrosoft.Owin.Security.Interop DataProtectionShim需要一个从共享机器密钥生成的DataProtectionProvider ,在文档中,这两个应用程序都引用了它来创建 cookie,并使用DataProtectionProvider.Create()方法将文件位置作为参数。

由于我们将DataProtection与 blob 存储结合使用,因此我们没有此位置。 我们已经尝试使用DataProtectionProvider.Create()在两个应用程序上只使用应用程序名称,因为它将使用 blob 存储密钥文件。 不幸的是,这不会创建一个可以跨两个应用程序工作的 cookie。

内OWIN Cookie身份验证设置OwinStartup

    app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = 'Identity.Application',
            AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
            LoginPath = new PathString("/login.aspx"),
            CookieName = "AppCookieName",
            ExpireTimeSpan = 300,
            SlidingExpiration = true,

            Provider = new CookieAuthenticationProvider
            {
                OnValidateIdentity =
                    SecurityStampValidator
                        .OnValidateIdentity<UserManager, User, int>(
                            validateInterval: TimeSpan.FromMinutes(30),
                            regenerateIdentityCallback: (manager, user) =>
                                manager.CreateIdentityAsync(user, 'Identity.Application'),
                            getUserIdCallback: (user) => user.GetUserId<int>())
            },
            TicketDataFormat = new AspNetTicketDataFormat(
                new DataProtectorShim(
                    DataProtectionProvider.Create("OurAppName")
                        .CreateProtector(
                            "Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware",
                            'Identity.Application',
                            "v2")
                        )),

            CookieManager = new ChunkingCookieManager()
        });

以及我们的 .Net Core Startup cookie 设置:

    services.AddAuthentication("Identity.Application")
        .AddCookie("Identity.Application", options =>
        {
            options.Cookie.Name = "AppCookieName";
        });

以前有没有人遇到过这种情况,我们发现的所有示例都只是使用DataProtectionProvider.Create()与机器密钥文件位置一起使用的示例,并且没有找到有关如何使用PersistKeysToAzureBlobStorage方法完成此操作的PersistKeysToAzureBlobStorage

我最终做的是(ab)使用 DI 系统(使用Microsoft.Extensions.DependencyInjection NuGet)来获得我想要的行为:

private static IDataProtector ConfigureDataProtection()
{
    // TODO this has to be wrong
    ServiceCollection services = new ServiceCollection();
    ConfigurationOptions configurationOptions = ConfigurationOptions.Parse("REDIS_CONNECTION_STRING_HERE");
    ConnectionMultiplexer rmp = ConnectionMultiplexer.Connect(configurationOptions);
    services.AddDataProtection()
        .SetApplicationName("APPNAME")
        .PersistKeysToStackExchangeRedis(rmp, "REDIS_DATA_PROTECTION_LIST_KEY");
    ServiceProvider provider = services.BuildServiceProvider();

    IDataProtectionProvider dataProtectionProvider = provider.GetRequiredService<IDataProtectionProvider>();
    return dataProtectionProvider.CreateProtector("Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", "Cookies" /* <- Auth Type to match the ASP.NET Core side, the rest is CRUCIAL and has to be the same purpose strings as internally used by ASP.NET Core */, "v2");
}

虽然我的示例使用了 Redis,但我想这同样适用于其他实现。

我试图做同样的事情,想要在新的 Asp.Net Core Web 应用程序和带有 Asp.Net Identity Authentication 的 Legacy WebForms 项目之间共享 cookie。

我希望这个答案可以帮助那些试图在 Asp.Net WebForms 中设置 cookie 身份验证的人,并能够将保护密钥存储在共享目录路径以外的其他地方。

"DataProtectionProvider.Create" provides an action with IDataProtectionBuilder which can be used to overwrite key directory and store key in cloud (azure blob storage)

如果 webforms 项目有 Azure.Extensions.AspNetCore.DataProtection.Blobs nuget 包安装密钥可以存储在 azure blob 存储中

例如

WebForms project identity cookie authentication setup.

app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                CookieName = $"SharedCookieName",
                CookieDomain = "SharedDomain",
                CookieSameSite = SameSiteMode.Lax,
                CookiePath = "/",
                CookieHttpOnly = true,
                ExpireTimeSpan = TimeSpan.FromMinutes(30),
                AuthenticationType = "Identity.Application",
                LoginPath = new PathString("/Account/Login"),
                Provider = new CookieAuthenticationProvider
                {
                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, int>(
                        validateInterval: TimeSpan.FromMinutes(30),
                        regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
                        getUserIdCallback: (id) => (id.GetUserId<int>()))
                },

                // Note: (new DirectoryInfo(@"\")  dummy directory to satisfy DataProtectionProvider.Create and than overwrite key storage with PersistKeysToAzureBlobStorage
                TicketDataFormat = new AspNetTicketDataFormat(new DataProtectorShim(DataProtectionProvider.Create(new DirectoryInfo(@"\"),
                                                        (builder) =>
                                                        {
                                                            builder.SetApplicationName("ShareApplicationName")
                                                            .PersistKeysToAzureBlobStorage("AzureBlobConnectionString","ContainerName", "key.xml");
                                                        })
                                                        .CreateProtector(
                                                           $"SomeSharedPurposeName",
                                                           "Identity.Application",
                                                           "v2"))),

                CookieManager = new Microsoft.Owin.Security.Interop.ChunkingCookieManager()
            });
IDataProtectionBuilder has multiple extension methods to use blob storage differently. 

public static IDataProtectionBuilder PersistKeysToAzureBlobStorage(this IDataProtectionBuilder builder, Uri blobSasUri)

public static IDataProtectionBuilder PersistKeysToAzureBlobStorage(this IDataProtectionBuilder builder, Uri blobUri, TokenCredential tokenCredential)

public static IDataProtectionBuilder PersistKeysToAzureBlobStorage(this IDataProtectionBuilder builder, Uri blobUri, StorageSharedKeyCredential sharedKeyCredential)

public static IDataProtectionBuilder PersistKeysToAzureBlobStorage(this IDataProtectionBuilder builder, BlobClient blobClient)

在设置应用程序 cookie 时,同样的方法可以与 Asp.Net Core 一起使用。

services.ConfigureApplicationCookie(options => { });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM