如何使用.Net Core在Azure中的应用程序之间共享Cookie身份验证?

时间:2017-09-27 20:37:30

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

我已经失去了至少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核心标识设置和表格)

现在,根据文章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帐户中的所有应用程序都无法共享应用程序之外的目录访问权限(我知道,是的,我知道他们还有其他选项可供选择文件共享,但我们现在就可以了。)

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

我们参考了这篇文章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();

此ALSO在本地运作!此代码在两个应用程序的ConfigureServices方法中,并允许在两个应用程序中读取cookie,但一旦部署,就不起作用!

有没有人能够实现这个或类似的东西?!

1 个答案:

答案 0 :(得分:0)

可能是因为默认情况下cookie不是跨子域。

您可以尝试将根域添加为Cookie域(这可能需要配置设置,因此它也适用于本地!)

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