【问题标题】:How can I share Cookie Authentication across apps in Azure with .Net Core?如何使用 .Net Core 在 Azure 中的应用之间共享 Cookie 身份验证?
【发布时间】:2018-03-09 11:17:21
【问题描述】:

我为此损失了至少 2 个完整的工作日,并尝试了多种方法来实现这一目标,但均未成功。

场景是这样的:我有 2 个应用程序部署到 Azure,假设它们是 backoffice.website.comfrontoffice.website.com。两者都是 2 个独立的 Azure Web 应用。登录到backoffice.website.com 的用户应该能够转到在frontoffice.website.com 登录的用户列表并选择要模拟的用户,这会将他们重定向到frontoffice.website.com,以所选用户身份登录。

两个网站在 Azure 中使用相同的数据库并共享相同的 DbContext(两个项目都在 Visual Studio 中使用相同的解决方案,并且都引用相同的数据访问层,它指向两个应用程序的数据库(两个应用程序都使用相同的 .Net Core Identity 设置和表格)

现在,根据here的文章。

您应该能够将Startup.ConfigureServices 方法设置为如下所示:

app.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
   options.Cookies.ApplicationCookie.AuthenticationScheme = "ApplicationCookie";
   var protectionProvider = DataProtectionProvider.Create(new DirectoryInfo(@"c:\shared-auth-ticket-keys\"));
   options.Cookies.ApplicationCookie.DataProtectionProvider = protectionProvider;
   options.Cookies.ApplicationCookie.TicketDataFormat = new TicketDataFormat(protectionProvider.CreateProtector("Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", "Cookies", "v2"));
});

这在本地使用 IIS Express 有效,但在 Azure 中,Azure 帐户中的所有应用程序都可以共享应用程序之外的目录访问权限(我知道,是的,我知道他们有其他选择文件共享,但我们现在就开始讨论)。

由于我们不能使用目录将具有 2 个应用程序之间所需的共享密钥的文件放在 Azure 的目录中,

我们参考这篇文章here,它导致在 Azure 中创建一个 Blob 容器来存储密钥,以便我希望在 Azure 中创建和托管的任何和所有应用程序都可以从存储中访问密钥。

使用引用的第一篇文章和第二篇文章中的位,代码现在看起来像这样(全部设置在Startup.ConfigureServices 方法中以提高可读性):

var storageAccount = new CloudStorageAccount(
            new StorageCredentials("blob", "SASKeyHere"),
            new StorageUri(new Uri("https://endpoint.blob.core.windows.net/")),
            null,
            null,
            null
        );

var client = storageAccount.CreateCloudBlobClient();
var container = client.GetContainerReference("container");
container.CreateIfNotExistsAsync().GetAwaiter().GetResult();

var serviceCollection = new ServiceCollection();
serviceCollection.AddDataProtection().PersistKeysToAzureBlobStorage(container, "fileName.xml");
 var service2 = serviceCollection.BuildServiceProvider();

 var dataProtector = service2.GetRequiredService<IDataProtectionProvider>();

 // Add framework services.
 services.AddDbContext<DbContext>(options => options
            .UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

 services.AddIdentity<ApplicationUser, IdentityRole>(options =>
            {
                options.Cookies.ApplicationCookie.AuthenticationScheme = "ApplicationCookie";
                var protectionProvider = dataProtector;
                options.Cookies.ApplicationCookie.DataProtectionProvider = protectionProvider;

                options.Cookies.ApplicationCookie.TicketDataFormat = new TicketDataFormat(protectionProvider.CreateProtector("Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", "Cookies", "v2"));
            })
            .AddEntityFrameworkStores<DbContext>()
            .AddDefaultTokenProviders();

这也适用于本地!此代码在两个应用程序的 ConfigureServices 方法中,并允许跨两个应用程序读取 cookie,但是一旦部署,就不起作用了!

有没有人能够做到这一点或类似的事情?!

【问题讨论】:

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


    【解决方案1】:

    这可能是因为 cookie 默认不跨子域。

    您能否尝试将您的根域添加为 cookie 域(这可能需要进行配置设置,因此它也可以在本地工作!)

    app.AddIdentity<ApplicationUser, IdentityRole>(options =>
    {
        options.Cookies.ApplicationCookie.CookieDomain = ".mydomain.com";
    }
    

    【讨论】:

    • 难以置信!这似乎有效,非常感谢您!值得注意的是,出于某种原因,要冒充用户的个人必须在登录“记住我”时选中复选框,否则该冒充对该用户不起作用。如果你也能帮助我理解这背后的原因,那就太好了。不过,它绝对可以只是我的代码。
    • 可能最适合另一个问题。我的建议是,对于像您这样的大问题,请尝试在 Github 上创建一个简单的 POC,并在您的问题中分享链接。我只是用这个在黑暗中刺了一下,但是对于模仿等,它太大了,无法真正猜出答案。
    猜你喜欢
    • 2020-05-18
    • 1970-01-01
    • 1970-01-01
    • 2019-08-17
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 1970-01-01
    • 2019-07-05
    相关资源
    最近更新 更多