Sharing Forms Cookie between asp.net web applications

Hi Guys,

This is my first blog and I was a bit confused so as from where to start. Few days back I came across requirement of a customer who wanted to share forms authentication across two different applications. We have one asp.net 2.0 application and that has a link to another 2.0 application. Whenever a user clicks on the link he expects to be taken to the second application. But when the users click’s on the link what do we see……….? Users are getting one more prompt for getting access to the second application. Important thing to note here is that the we are suppose to get this prompt as the second application doesn’t have any knowledge of the cookie that has issued to the first application and hence the prompt. Is now the question is that is it really possible to achieve this requirement?

The Answer is yes. But we have to do few changes to the web.config for the applications so that both the applications understand the cookie and then we won’t get the prompt.

First step is to make sure that the “loginUrl” web.config of the second application points to the loginUrl of the first application as shown below.

<configuration>

  <system.web>

    <authentication mode="Forms" >

      <! -- The name, protection, and path attributes must match exactly in each Web.config file. -->

      <forms loginUrl="../form1/MyLoginPage.aspx"

      name=".ASPXFORMSAUTH"

      protection="All"

      path="/"

      timeout="30" />

    </authentication>

    <!-- Validation and decryption keys must exactly match and cannot be set to "AutoGenerate". The validation and decryption algorithms must also be the same. -->

 <machineKey

validationKey="C50B3C89CB21F4F1422FF158A5B42D0E8DB8CB5CDA1742572A487D9401E3400267682B202B746511891C1BAF47F8D25C07F6C39A104696DB51F17C529AD3CABE"

decryptionKey="8A9BE8FD67AF6979E7D20198CFEA50DD3D3799C77AF2B72F"

validation="SHA1" />

  </system.web>

</configuration>

Unless otherwise noted, the name, protection, path attributes must be identical across all applications. Similarly, the encryption and validation keys and the encryption scheme and validation scheme used for cookie data must be exactly the same. If the settings do not match, cookies cannot be shared.

To Generate the machine keys follow the steps mentioned below.

Create the project

Create a Visual C# .NET console application:

1.

Start Visual Studio .NET.

2.

On File menu, point to New, and then click Project.

3.

Under Project Types, click Visual C# Projects.

4.

Under Templates, click Console application.

5.

Name the project HashConfigCs.

6.

Click OK.

Write the code to generate the keys

The following code reads two arguments that are passed from the command line: • The first argument is the number of bytes that is used to create the decryptionKey attribute.

• The second argument is the number of bytes that is used to create the validationKey attribute.

The code uses a random number generator to create a random number of bytes based on the command-line arguments. After the random bytes are created, the bytes are formatted into a hexadecimal string that is suitable for use in the .config files.

The hexadecimal string that is created is twice the size of the value that is passed on the command line..

Add the following code to a .cs file: using System;

using System.Text;

using System.Security.Cryptography;

namespace Crypto

{

    public class KeyCreator

    {

        public static void Main(String[] args)

        {

            String[] commandLineArgs = System.Environment.GetCommandLineArgs();

            string decryptionKey = CreateKey(System.Convert.ToInt32(commandLineArgs[1]));

            string validationKey = CreateKey(System.Convert.ToInt32(commandLineArgs[2]));

            Console.WriteLine("<machineKey validationKey=\"{0}\" decryptionKey=\"{1}\" validation=\"SHA1\"/>", validationKey, decryptionKey);

        }

        static String CreateKey(int numBytes)

        {

            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();

            byte[] buff = new byte[numBytes];

            rng.GetBytes(buff);

            return BytesToHexString(buff);

        }

        static String BytesToHexString(byte[] bytes)

        {

            StringBuilder hexString = new StringBuilder(64);

            for (int counter = 0; counter < bytes.Length; counter++)

            {

                hexString.Append(String.Format("{0:X2}", bytes[counter]));

            }

            return hexString.ToString();

        }

    }

}

Generate the hashes

Now you can compile the application.

Run the application from a command prompt by passing in two integer values that are the size of the decryption and the validation keys. For example, if you named the console application HashConfigCs.exe, type the following syntax from the command line in the Bin\debug directory of the application:

hashconfigcs.exe 24 64

You can expect the application to return output that is similar to the following output:

<machineKey validationKey="21F090935F6E49C2C797F69BBAAD8402ABD2EE0B667A8B44EA7DD4374267A75D7AD972A119482D15A4127461DB1DC347C1A63AE5F1CCFAACFF1B72A7F0A281B"

            decryptionKey="261F793EB53B761503AC445E0CA28DA44AA9B3CF06263B77"

            validation="SHA1"/>

Then try the link and boom… it works J

Hope this helps in case of similar requirements.