Sunday, January 17, 2016

Understanding the ADFS Token Signing and Decrypting Certificates Rollover Process

Active Directory Federation Services (ADFS) creates and manages the two certificates used for the tokens issued. These are the Token-signing and Token-decrypting certificates. By default, these certificates are valid for one year from their creation and around the one-year mark, they will renew themselves automatically via the Auto Certificate Rollover feature in ADFS. Once this happens, CRM can no longer properly authenticate users as it still holds the old certificates’ metadata in the database. This is easily resolved by rerunning the “Configure Claims Based Authentication” and “Configure Internet Facing Deployment” wizards from the CRM Deployment Manager and then issuing an IISRESET on the CRM server(s). More details and resolution can be found in this KB: http://support.microsoft.com/kb/2686840

While most CRM administrators understand that aspect, there are a number of settings and configurations that lead up to this issue that are less well-known to most. One of the biggest complexities is understanding EXACTLY when CRM will be going down because of the Auto Certificate Rollover and how to avoid it. We will be going through that today.

We will start with the process that ADFS goes through for certificate renewal:

  1. ADFS determines that its certificates will be expiring soon.
  2. ADFS creates new certificates and sets them as secondary certificates.
  3. ADFS updates the new certificates to primary certificates.

There are a number of settings for ADFS only accessible via PowerShell that control the Auto Certificate Rollover options and properties for the process above. To access these, open an administrative PowerShell prompt and execute the following (Note that if you are using ADFS 2.0, you will need to add the ADFS PowerShell Snap-In first by executing Add-PSSnapin Microsoft.ADFS.PowerShell):


Get-ADFSProperties

This will display a listing of the deployment properties for ADFS, including the properties around the certificates and rollover. For our purposes, we will keep our focus on just a handful of these properties:

  • AutoCertificateRollover
  • CertificateDuration
  • CertificateGenerationThreshold
  • CertificatePromotionThreshold
  • CertificateRolloverInterval



So what do all of these values mean? Below are the same steps provided earlier but now account for the values in the table above.

  1. ADFS determines that its certificates will be expiring within 20 days.
  2. ADFS creates new certificates valid for 365 days and sets them as secondary certificates.
  3. After 5 days’ time the Certificate Management Cycle kicks off and ADFS updates the new certificates to primary certificates.

As you can see, knowing these values can greatly help in planning for certificate rollover. Here is an example:

In the screenshot below, we can see our primary certificates expire on 2/12/2015 and ADFS has already created new certificates to rollover. The new (secondary) certificates were created 20 days prior to the expiration of the primary certificates (1/23/2015). On 1/28/2015, 5 days after the creation of the new certificates, ADFS will change them to primaries.




Great. So what now? BEAT ADFS TO THE PUNCH!

In the above example, you know your deadline is 1/28/2015. Rather than sitting back and waiting until CRM goes down, plan a short outage afterhours and roll the certificates over manually! You can force ADFS to generate new certificates and promote them to primaries immediately using the following command in PowerShell:

Update-ADFSCertificate –Urgent

Once the new certificates are in place in ADFS, re-run the Claims and IFD Wizards in the CRM Deployment Manager to update the metadata and issue an IISReset on the CRM server(s). Voila! Happy CRM users!

Of course, given the properties we have at our disposal to modify there is much more you can do to create a better life for yourself. For example, set the CertificateDuration to 1095 days (three years) rather than just 365 (one year) so this is not as frequent of an issue. Another idea would be to set the CertificateGenerationThreshold lower so the actual rollover date is closer to the true expiration of the certificate. Or just turn off AutoCertificateRollover altogether, set a reminder, and take care of it all manually before expiration!

Saturday, January 9, 2016

CRM 2016 New Form Rendering Engine


With the release of CRM 2016 (2015 Update 1 for CRM Online), comes a new form rendering engine built to provide better performance of form loads. The two main changes are focused around loading process of the form and the handling of the cache.

However, while the new rendering engine was built to help with performance you may actually notice the opposite taking place. In heavily customized environment, you might experience long stalls during form loads with messages reading “requesting data from CRM” and/or “loading business logic”.
If you are currently being plagued by these messages, it may be a good idea to turn the new rendering engine off. To do this, simply go to: Administration -> System Setting, scroll all the way down and you will see the “Use legacy form rendering” option. Turning it to “yes” will disable the new engine.



While this will help in the short term, it is advised to figure out what on your form is causing conflict with the new engine so that it can be fixed and the new engine can be turned back on for even better performance.

Monday, January 4, 2016

ADFS Logon Page Loop Issue

I recently setup CRM 2015 and ADFS 3.0 (the version that comes on Server 2012 R2, aka ADFS 2.2) on new servers for a customer. Everything configured fine and initial tests proved successful when logging in with the domain admin account used to set everything up. However, I quickly found an issue when other users tried to access CRM via the external URL. At the ADFS login page, a user would enter his or her credentials as usual and try to login but rather than giving a 302 redirect back to CRM for access, it redirected back to the ADFS login page. This presented no errors on screen or in the CRM event viewer – it was as if I never tried logging in. If I purposefully entered invalid credentials, it provided the error regarding incorrect user ID or password so I knew authentication against AD was taking place successfully and that something was wrong with the passing of the token.  Also of note was the fact that despite the external URL not working, all users were able to access CRM just fine using the internal (pass-through auth) URL.


Nothing appeared in the ADFS Admin event viewer logs but upon closer inspection, the Security log in the event viewer on the ADFS server was loading up with Audit Failure notifications – Event ID 4625. The failure reason indicated “Unknown user name or bad password” for the ADFS service account. As any logical person would assume, I figured the account was locked out, the password expired, or I entered invalid credentials during setup. Unfortunately, upon resetting the password in Active Directory, the audit failures persisted.



After some digging around, I uncovered that adding the ADFS service account to the Windows Authorization Access Group in Active Directory was the resolution. The members of this group have access to the computed tokenGroupsGlobalAndUniversal attribute on User objects. I added the account to the group, restarted the ADFS service, and all users were then able to access CRM via the external URL as expected!



UPDATE (1/27/16) - While adding the ADFS service account to the Windows Authorization Access Group fixed the issue for most users accessing CRM, it managed to rear its ugly head for a handful of users again. The fix this time was similar - I added the account to the Pre-Windows 2000 Compatible Access Group. Users in this group have read access over all users in the domain. Typically, the 'Everyone' group is present in here by default so this is not usually an issue but this customer in particular removed it. So to conclude, make sure group membership is set on both of these groups if you are experiencing the loop issue.