Sharing authentication cookie among Asp.Net Core 1 (MVC6) and MVC 5 applications

醉酒当歌 提交于 2019-12-23 01:11:31

问题


I have a few MVC 5 applications that share the same authentication cookie. I'm using ASP.NET Identity to create the cookie.

I checking if the user is authenticated using Owin's helper method, like so:

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

And in all applications using this cookie, I have the following config in the web.config file:

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

As I understand, this configuration allows the applications to decrypt the same cookie.

In the MVC6 application I'm setting it up to use the cookies like this:

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

OK, here's my problem the configuration is already different, as I don't know to specify the provider nor the authentication type.

After, I'd have to config the decryption key, but as I understand MVC 6 doesn't have a web.config file. So how can I achieved this?


回答1:


Disclaimer: this answer is applicable to RC2 only, which should be released mid-May. It may work with RC1, but would require more work.


You can use the new Microsoft.Owin.Security.Interop package to make the OWIN/Katana cookies middleware use the new serialization format and the new data protection stack used by ASP.NET Core (the other way around would be much harder, and definitely not recommended):

OWIN/Katana app:

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 app:

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";
        });
    }
}

You should be able to remove the machineKey node in your web.config if you're only using it for the cookies middleware, as the OWIN/Katana cookies middleware will now use the new data protection stack, that doesn't rely on machine keys but on a key ring persisted on the machine (by default, in either the registry or in a special folder).

If your apps are deployed on different machines, I'd recommend synchronizing the key rings across your machines. You can read this other SO post for more information.




回答2:


I would highly recommend moving to OAuth 2.0 or OpenID Connect to authenticate once between your multiple applications, but barring that, what you will want to do is look at the Data Protection API.

  • Configuring Data Protection:

    https://docs.asp.net/en/latest/security/data-protection/configuration/overview.html

  • Understanding how the default settings work:

    https://docs.asp.net/en/latest/security/data-protection/configuration/default-settings.html

In order to obtain configuration values to use with the API, instead of web.config you may use one of the following approaches:

  • a .json file or some other type of file that is deployed as part of an automated deployment process and conditionally loaded when your app starts up
  • environment variables configured on the server, possibly in applicationHost.config for IIS for that application pool (requires IIS 10.0 or greater for app pool environment variables, or if you are using the HttpPlatformHandler/AspNetCoreModule you can configure environment variables for that)
  • Whatever else your imagination can come up with

You can read more about possible options for configuration at this documentation page:

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




回答3:


I got an easier solution (for my case) on ASP.NET Core side - no need to modify the ASP.NET 4 side:

I just built a simple IDataProtector (like the shim above), which does the following in Unprotect method:

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);
}


来源:https://stackoverflow.com/questions/37094782/sharing-authentication-cookie-among-asp-net-core-1-mvc6-and-mvc-5-applications

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!