.Net 和 Core 上跨子域的 ASP.NET Identity Cookie

Sur*_*rya 6 cookies webforms data-protection asp.net-identity asp.net-core

我有许多托管在主域和子域上的应用程序:

网站 A,ASP.NET (.Net Core 2.0),网址为 www.example.com

网站 B,ASP.NET MVC (4.7 .net Framework),位于 site.example.com

网站 C,ASP.NET Identity (.Net Core 2.0),位于 account.example.com

网站 D,ASP.NET Webform(4.7 .net Framework),位于 file.example.com

我想在account.example.com上登录使用,经过身份验证后,用户将重定向到其他网站。他们将获得其他网站上角色的授权。

我正在尝试在这些网站之间共享 cookie,并且所有网站都托管在Azure Web App上。

我正在使用ASP.NET Identity (.Net Core 2.0)。我正在使用内置的 cookie 身份验证。

如何在所有应用程序中使用数据保护并在它们之间共享 cookie。

对于数据保护,我的代码是:

 services.AddDataProtection()
            .SetApplicationName("example")
            .PersistKeysToFileSystem(new DirectoryInfo(@"%HOME%\ASP.NET\DataProtection-Keys"))
            .SetDefaultKeyLifetime(TimeSpan.FromDays(14));
Run Code Online (Sandbox Code Playgroud)

对于 Cookie 身份验证,我的代码是:

 app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            CookieDomain = ".example.com"
        });
Run Code Online (Sandbox Code Playgroud)

Sur*_*rya 8

我从这个微软文档中得到了解决方案

使用 ASP.NET 和 ASP.NET Core 在应用程序之间共享 cookie

以及该子域认证系统的示例代码

Cookie 共享示例应用程序 - GitHub

该示例说明了三个使用 cookie 身份验证的应用程序之间的 cookie 共享:

  • 不使用 ASP.NET Core Identity 的 ASP.NET Core 2.0 Razor Pages 应用
  • 具有 ASP.NET Core Identity 的 ASP.NET Core 2.0 MVC 应用程序
  • 具有 ASP.NET Identity 的 ASP.NET Framework 4.6.1 MVC 应用程序

将此代码放入 Startup.cs 中的 ConfigureServices 方法中

services.AddDataProtection()
.PersistKeysToFileSystem(GetKeyRingDirInfo())
.SetApplicationName("example");

services.ConfigureApplicationCookie(options => 
{   
options.Cookie.Name = "example";
options.Cookie.Domain = ".example.com";
});
Run Code Online (Sandbox Code Playgroud)

对于KeyRing方法

private DirectoryInfo GetKeyRingDirInfo()
    {
        var startupAssembly = System.Reflection.Assembly.GetExecutingAssembly();
        var applicationBasePath = System.AppContext.BaseDirectory;
        var directoryInfo = new DirectoryInfo(applicationBasePath);
        do
        {
            directoryInfo = directoryInfo.Parent;

            var keyRingDirectoryInfo = new DirectoryInfo(Path.Combine(directoryInfo.FullName, "KeyRing"));
            if (keyRingDirectoryInfo.Exists)
            {
                return keyRingDirectoryInfo;
            }
        }
        while (directoryInfo.Parent != null);

        throw new Exception($"KeyRing folder could not be located using the application root {applicationBasePath}.");
    }
Run Code Online (Sandbox Code Playgroud)

注意:您必须复制在身份应用程序托管服务器上自动生成的KeyRing文件,并手动粘贴到其他网站的其他子域和主域托管服务器以共享cookie以进行身份​​验证。