We have a situation where we created a couple of SharePoint farms, QA and Production, that had some customized FBA implementations and implemented reversible encryption for the passwords. Since the passwords are coming from a legacy system, we had to come up with a way to encrypt them and make them “decryptable” within SharePoint. We were successful in doing this, but ended up having a couple of issues in production that would not allow users to log in. Basically, their passwords were not being decrypted correctly.
This all begins in the <machineKey> section of the web.config. The decryptionKey is used during the decryption process and, since this had to be supported across multiple machines, we made these sections the same across multiple machines and farms. In fact, we had to use this on our legacy system so we could successfully encrypt and transfer the passwords from the AS400 (yes, mainframe). This is what a <machineKey> section looks like.
<machineKey validationKey="8C3B5469A19FA84540F9B9E353679822934EF13EA0C26887B2AD4A6CA139BBBB" decryptionKey="634A6FD0D98D0A254D5E54F9D35287244C9DEB23A029BCAEA1C4FE21874C63AF" validation="HMACSHA256" />
When SharePoint is installed, it records some of the portions of the web.config file in the SharePoint configuration database. These are located in the Objects table.
Allen Wang had a good blog post on the issue: http://blogs.msdn.com/b/allenwang/archive/2012/03/23/sharepoint-2010-health-analyser-timer-job-changed-custom-web-config-machine-key.aspx. Here he identifies how to find the keys in the Objects table. Here is a select statement with a part of the offending decryption key in the WHERE clause.
This returns exactly one record. Copy and paste it in something like Notepad++ so you can see it more easily.
Apply some XML formatting to more easily wade through the XML. Here you’ll find m_ViewStateValidationKey and m_ViewStateDecryptionKey that correspond to the validationKey and decryptionKey in the <machine.config>
These were initially set when SharePoint was installed and, to my knowledge, there is not a “supported” way to change them in the config database. Of course, any of us could change these in the database, but if you do make a good backup in case you need to put it back!
I can reason through why they do this. Since the view state data is being encrypted/decrypted and there could be multiple WFEs, you certainly don’t want these values to be different across WFEs, lest your requests bounce across WFEs, as different values would yield different results, i.e. reading the view state would break. That would be a mess. So, they created a Health Analyzer rule to insure these values remain the same across WFEs. Health Analyzer rules are viewed within the Monitoring section of SCA.
Here is the rule in the Health Analyzer. Web.config files are not identical on all machines in the farm. You can see I have already disabled this rule.
I actually disabled this rule using the PowerShell command. Here the rule name is ViewStateKeysAreOutOfSync.
Here you can see the relationship between the Name of the rule and the Summary of the rule from the PowerShell command, Get-SPHealthAnalysisRule ViewStateKeysAreOutOfSync.
Now, most of the solutions to this issue I’ve read employ PowerShell to disable this Health Analyzer rule, as shown previously. However, you can also manage rules in the web interface. The rules are in a SharePoint list, so simply click on the rule and edit it.
Here you can see there is another setting, Repair Automatically. This is likely the culprit that is changing the web.config. A Health Analyzer rule can be set to report the issue and/or attempt to repair the issue. So, instead of disabling the rule completely, you can simply stop it from attempting to repair the issue.