【问题标题】:Sharing authentication cookie among Asp.Net Core 1 (MVC6) and MVC 5 applications在 Asp.Net Core 1 (MVC6) 和 MVC 5 应用程序之间共享身份验证 cookie
【发布时间】:2017-03-28 03:23:04
【问题描述】:

我有几个共享相同身份验证 cookie 的 MVC 5 应用程序。我正在使用 ASP.NET Identity 来创建 cookie。

我检查用户是否使用 Owin 的辅助方法进行了身份验证,如下所示:

app.UseCookieAuthentication(
    new CookieAuthenticationOptions
    {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        ExpireTimeSpan = TimeSpan.FromMinutes(expirationTimeInMinutes),
        LoginPath = new PathString("/Account/Login"),
        Provider = new CookieAuthenticationProvider()
    });

在所有使用此 cookie 的应用程序中,我在 web.config 文件中有以下配置:

<machineKey validationKey="..." decryptionKey="..." validation="SHA1" />

据我了解,此配置允许应用程序解密相同的 cookie。

在 MVC6 应用程序中,我将其设置为使用这样的 cookie:

app.UseCookieAuthentication(options =>
  {
    //options.AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie;
    options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
    options.LoginPath = new PathString("/Account/login");
    //options.Provider = new CookieAuthenticationProvider()
  });

好的,这是我的问题,配置已经不同,因为我不知道指定提供者或身份验证类型。

之后,我必须配置解密密钥,但据我了解,MVC 6 没有 web.config 文件。那么我该如何实现呢?

【问题讨论】:

  • 这两个网站是同一个域名吗?
  • 是的,它们在同一个域中。

标签: asp.net-mvc asp.net-identity


【解决方案1】:

免责声明:此答案仅适用于 RC2,应该会在 5 月中旬发布。它可能适用于 RC1,但需要更多的工作。


您可以使用新的Microsoft.Owin.Security.Interop 包使 OWIN/Katana cookie 中间件使用新的序列化格式和 ASP.NET Core 使用的新数据保护堆栈(反之亦然,而且绝对不会推荐):

OWIN/Katana 应用程序:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        // Create a new data protection provider with a unique app
        // name shared by both your OWIN/Katana and ASP.NET Core apps:
        var provider = DataProtectionProvider.Create("your app name");

        // Create a protector compatible with the ASP.NET Core cookies middleware.
        // Replace the second argument ("Cookies") by the authentication scheme
        // used by your ASP.NET Core cookies middleware if necessary.
        var protector = provider.CreateProtector(
            "Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware",
            "Cookies", "v2");

        // Set TicketDataFormat to force the OWIN/Katana cookies middleware
        // to use the new serialization format used by ASP.NET Core:
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            TicketDataFormat = new AspNetTicketDataFormat(new DataProtectorShim(protector))
        });
    }
}

ASP.NET Core 应用:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDataProtection(options =>
        {
            // Force the ASP.NET Core data protection stack to use
            // the name shared with your OWIN/Katana app.
            options.ApplicationDiscriminator = "your app name";
        });
    }
}

如果您仅将 machineKey 节点用于 cookie 中间件,您应该能够删除 web.config 中的节点,因为 OWIN/Katana cookie 中间件现在将使用新的数据保护堆栈,这不会t 依赖于机器密钥,但依赖于机器上持久存在的密钥环(默认情况下,在注册表或特殊文件夹中)。

如果您的应用部署在不同的机器上,我建议在您的机器上同步密钥环。您可以阅读this other SO post 了解更多信息。

【讨论】:

  • 我可以试试这个夜间版本吗?
  • 您可以使用 aspnetcirelease feed 来尝试预发布的 RC2 构建,但请注意 VS 不能很好地使用这些新软件包(至少在新的 CLI 工具发布之前):@ 987654322@
  • 谢谢。目前,我只需要一个 POC,新的 AspNetCore 将与我们现有的应用程序一起工作。
  • 会的,前提是您可以更新现有应用以使用新的序列化/数据保护块。
  • 是的,我可以。谢谢,我下午晚些时候试试。
【解决方案2】:

我强烈建议您迁移到 OAuth 2.0 或 OpenID Connect,以便在您的多个应用程序之间进行一次身份验证,但除此之外,您需要查看数据保护 API。

为了获取与 API 一起使用的配置值,您可以使用以下方法之一,而不是 web.config:

  • .json 文件或其他类型的文件,作为自动部署过程的一部分部署并在您的应用启动时有条件地加载
  • 在服务器上配置的环境变量,对于该应用程序池的 IIS,可能在 applicationHost.config 中(应用程序池环境变量需要 IIS 10.0 或更高版本,或者如果您使用的是 HttpPlatformHandler/AspNetCoreModule,则可以为此配置环境变量)
  • 您还能想到什么

您可以在此文档页面上阅读有关可能的配置选项的更多信息:

https://docs.asp.net/en/latest/fundamentals/configuration.html

【讨论】:

    【解决方案3】:

    我在 ASP.NET Core 方面得到了一个更简单的解决方案(就我而言) - 无需修改 ASP.NET 4 方面:

    我刚刚构建了一个简单的 IDataProtector(如上面的 shim),它在 Unprotect 方法中执行以下操作:

    public byte[] Unprotect(byte[] protectedData)
    {
        // ... call the Unprotect method of the "shimmed" protector,
        // you'll get back the bytes
    
        // now make the Owin serializer to deserialize the old format
    
        Microsoft.Owin.Security.DataHandler.Serializer.TicketSerializer owinSerializer =
                new Microsoft.Owin.Security.DataHandler.Serializer.TicketSerializer();
    
        Microsoft.Owin.Security.AuthenticationTicket owinTicket = owinSerializer.Deserialize(cookie);
    
        // now build the ticket for the new format
    
        Microsoft.AspNetCore.Authentication.AuthenticationTicket coreTicket = new
                Microsoft.AspNetCore.Authentication.AuthenticationTicket(
                new System.Security.Claims.ClaimsPrincipal(owinTicket.Identity), 
                new Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties(owinTicket.Properties.Dictionary), 
                _purpose);
    
        Microsoft.AspNetCore.Authentication.TicketSerializer coreSerializer = 
            new Microsoft.AspNetCore.Authentication.TicketSerializer();
    
        // and return the new format, serialized - this will work
    
        return coreSerializer.Serialize(coreTicket);
    }
    

    【讨论】:

      猜你喜欢
      • 2018-10-04
      • 1970-01-01
      • 1970-01-01
      • 2015-06-03
      • 2015-06-15
      • 2019-07-05
      • 2020-05-18
      • 1970-01-01
      • 2017-06-27
      相关资源
      最近更新 更多