There is an easy way to implement Single Sign On in MVC5 domains

Scenario:

Two separate web projects working with these domains:

  • account.ilovepandas.com
  • ilovepandas.com

Using the ASP.Net identifier, is there an easy way to implement a common login in MVC5 so that if a user logs in to ilovepandas.com and goes to account.ilovepandas.com, will it be authenticated?

I did research on this topic, and there are some fairly complex solutions, such as Thinktecture, the OWIN authorization server. I hope that since MVC4-5 gave us a big revision of Identity, there may now be an easier solution that I just could not find.

It would seem that I was as simple as letting them share an auth-cookie.

+1
source share
1 answer

TL DR: Assuming both applications use the same top level domain, you can share the authentication cookie. Set the domain in the cookie and share any keys necessary to decrypt it between applications.

Here I assume that you are using FormsAuthentication.

1) Add the domain attribute to the authentication/forms section:

 <authentication mode="Forms"> <forms loginUrl="~/account/login" timeout="2880" defaultUrl="~/" slidingExpiration="true" protection="All" domain=".yourdomain.tld" name="YOUR_COOKIE_NAME" /> 

Pay attention to the main period in the domain.

2) In order for both applications to decrypt the cookie, you need to add machineKey for both and use the same verification and encryption keys:

 <machinekey compatibilitymode="Framework45" validation="HMACSHA256" validationkey="YOURVALIDATIONKEYHERE" decryption="AES" decryptionkey="YOURDECRYPTIONKEYHERE" /> 

You can use the machine key tool in IIS Manager (provided that you have access to the web server) or some other tool receives valid keys. If you need a suggestion, I created an application in which you can use it here that refers to the Github project if you want to generate your own keys.

For completeness:

Here is the class that will generate the valid keys:

 public class KeyGenerator { public string GenerateKey(int length, bool useUpperCase = true) { byte[] buffer = new byte[length]; var randomNumberGenerator = new RNGCryptoServiceProvider(); randomNumberGenerator.GetBytes(buffer); return ToHexString(buffer, true); } private static string ToHexString(byte[] bytes, bool useUpperCase = false) { var hex = string.Concat(bytes.Select(b => b.ToString(useUpperCase ? "X2" : "x2"))); return hex; } } 

And you will use something like this to get the keys:

 var generator = new KeyGenerator(); /* 512 bits = 64 bytes (512 / 8) */ string validationKey = generator.GenerateKey(64); /* 256 bits = 32 bytes (256 / 8) */ string decryptionKey = generator.GenerateKey(32); 
+2
source

Source: https://habr.com/ru/post/1015238/


All Articles