web.config Encryption and SharePoint

This post comes form another question generated from a customer.  I have encrypted my web.config section and I want to be able to pull that information out of
the configuration file. That’s easy right, .NET takes care of that?  Typically it does, given the right permissions were granted in IIS and that everyone connected as
the same user. 

If you encrypt the web.config file in SharePoint there are some interesting things that can happen.  If you are a user with administrator rights and the first person
to use a portion of the site that requires those encrypted configuration items you will feel that nirvana has been reached with your solution. 
No more testing needed.  :-).  My solution is ready for QA!

How many of us have been there before the dreaded move to QA.  :-(.  Turns out that if the admin group is the first to reference the site after the encryption
change all is good.  If anyone else is the first person to enter the site that needs encrypted info, SharePoint bombs and gives the following error:

 Configuration Error
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.

Parser Error Message: Failed to decrypt using provider 'RsaProtectedConfigurationProvider'. Error message from the provider: The RSA key container could not be opened.

 

 

This happens because the user doesn’t have access to the registry keys required to read the encrypted information.  More information can be found here,
https://msdn.microsoft.com/en-us/library/ms998283.aspx.  Because SharePoint impersonates the user you would need to script the entire user base and give
them access to the key.  So how do you make this work?  What we implemented was a solution that leveraged the SPSecurity.RunWithlElevatedPrivileges
delegate to make all calls to the ConfigurationManager.  This seemed to make things OK regardless of who accesses the site first.  For those of you dealing with
CAS, you will also need to grant the following permissions:

 

 <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="Assertion, Execution, ControlThread, ControlPrincipal, RemotingConfiguration, UnmanagedCode"  />
<IPermission class="Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" version="1" ObjectModel="True" Impersonate="True" UnsafeSaveOnGet="True"/>

 

 

 public static Configuration Settings
{ 
    get 
    {
        if ( _config == null )
        {
            SPSecurity.RunWithElevatedPrivileges( 
               delegate()
               {
                   _config = ConfigurationManager.GetSection( "mydata" ) as Configuration;
               } 
            );
        }

        return _config; 
    }
}