parliament
parliament

Reputation: 22964

Create MVC 3 ASPXAUTH cookie from MVC 5.1 application - Single Sign on

I have 2 seperate websites, the main one running .NET 4.5 MVC 5.1 the other on a subdomain running .NET 4.0 MVC3.

I want to do single sign-in so when the user logs into the main site I need to set a cookie for the subdomain to read as if the user is logged in there too. The problem is calling FormsAuthentication.SetAuthCookie with the same paramters from the 2 application results in a different cookie. I need to create an MVC 3 ASPXAUTH cookie from the MVC 5.1 application

Simply using the MVC 5.1 generated cookie doesn't log the user into the MVC 3 application. I've set the machine key to the same for both application but the one generated by MVC3 is about 50 characters longer than the one I set (total is something like 150+ characters).

Actually here's the 2 cookies:

using System.Web.Security.Cryptography;
byte[] binaryMVC3Cookie = CryptoUtil.HexToBinary("0B406403C8FB8DE06FBF43291C48BED31C41FC2DCDFB81541A65A2B842E63B609FA6D146F3CF68968240ED5D5EF75A2FEC2C0D4B4FF99CD4DAF974D264A08D794BBF75EB6C4F40F08F9A6A97B1A4E130B9FC9CC9E5C55E93D06D9A9D56427110637874DA4059D18D0D4929DE04360DF72E13DB09");
byte[] binaryMVC5Cookie = CryptoUtil.HexToBinary("6D0C1B88CC6FB663B59FBAEC4BBDF02751C8EC70F2988BBC175F750AF7CE32412BFB2C8F79D24B0E6E832A51CCF479D7492A49D808A8C101FAB050E410D8F561BD7944694DF7DD74F09CF348D1BDD7E2BC0D9709");

FormsAuthentication.Decrypt() works fine on the MVC5 cookie (of course since it was generated there) but it throws a Cryptography exception for the MVC 3 cookie. So I decompiled the assembly and executed lines of interest in the Immediate Window to find that the exception is throw internally from the following line:

ICryptoService cryptoService = AspNetCryptoServiceProvider.Instance.GetCryptoService(Purpose.FormsAuthentication_Ticket, CryptoServiceOptions.None);
byte[] numArray = cryptoService.Unprotect(binaryMVC3Cookie); //Here exception 

I'm going to need to recreate that MVC 3 cookie from my MVC 5.1 app. If anyone has any ideas please do tell!

EDIT: I just had an epiphany how to circumvent all hackery. I'll just make a WebClient call to the MVC 3 app and get the correct cookie value. =O (Note making a WebClient call to the login method on the MVC3 application and having it call FormsAuthentication.SetAuthCookie did NOT work. I had to actually send the cookie value over and set it as a subdomain cookie in the main app

Upvotes: 2

Views: 1532

Answers (3)

Levi
Levi

Reputation: 32828

We improved the entire cryptographic stack in ASP.NET 4.5. The end result is that the forms authentication ticket format is different for your MVC 3 (.NET 4.0) application vs. your MVC 5.1 (.NET 4.5) application.

See http://blogs.msdn.com/b/webdev/archive/2012/10/23/cryptographic-improvements-in-asp-net-4-5-pt-2.aspx for lots more info on this. Here's an excerpt from that document detailing how to achieve backward compatibility so that you can share cookies between .NET 4.0 and .NET 4.5 applications:

If you are writing an application targeting ASP.NET 4.5 (you have set <httpRuntime targetFramework="4.5" />) and you need to share tickets with applications running earlier versions of ASP.NET, you must set the following in the 4.5 project's Web.config:

<machineKey compatibilityMode="Framework20SP1" />

Upvotes: 2

parliament
parliament

Reputation: 22964

Ok so my ephiphany edit in the question worked successfully to accomplish the real end goal which was single-sign on across MVC5 and MVC3. What I did was make an Http request using WebClient class. In MVC3 I used FormsAuthentication.GetAuthCookie and send the cookie.Value over to the MVC 5 application where I set it as a subdomain cookie:

  HttpCookie forumAuthCookie = new HttpCookie(".ASPXAUTH", response.CookieValue);
  forumAuthCookie.Domain = ".site.com";
  HttpContext.Current.Response.Cookies.Add(forumAuthCookie);

Upvotes: 0

PeterFromCologne
PeterFromCologne

Reputation: 10483

We have multiple web apps on the same server and they all share the same login as well. We set a fixed generated *machine.key* in the machine.config so that all apps share it

this works fine for us. I haven't tried your specific situation with a mix of claim and form authentication, but maybe you could give it a try.

see How To: Configure MachineKey in ASP.NET 2.0 it's old but still applies.

Upvotes: 1

Related Questions