Security Tips 1: Claims and Security Related Tips in SharePoint 2010

SharePoint 2010

Summary:  Learn five tips that are related to claims-based authentication and Secure Store Service in Microsoft SharePoint 2010, including configuring Secure Store Service, using certificates, and downloading IRM documents.

Recently, I fought with the issue of configuring the Secure Store Service to use accounts across a one-way trust in Microsoft SharePoint Server 2010, and did not find any information about it anywhere. So, I thought I would share, in case someone else runs across it.

Let's assume that you have SharePoint Server 2010 installed in a classic resource forest scenario. The SharePoint farm is in what is called a "Resources" forest; it has a one-way, outgoing trust with the "Users" forest, where all of the user accounts live. This means that the Resources forest trusts the accounts from the Users forest, but Users does not trust the accounts from Resources.

So what happens if you want to add accounts from the Users forest into a Secure Store Service target application? Well, you just need to do the same kind of people picker customization that you would be doing for your content web applications, except that you need to do it for the central administration web application in this case. For example, to select and resolve accounts from the Users forest in your end-user web applications, you would run the command stsadm -o setproperty -propertyname peoplepicker-searchadforests -propertyvalue thisIsAnExample -url http://yourWebApp. To enable this scenario, you just run the same command, except the -url parameter should be http://urlToCentralAdministration. After you make that change, you should be good to go.

I noticed an unusual wrinkle recently when using the Secure Store Service in a custom claims provider that I was working on. This is actually an interesting scenario because I was doing what many folks want to do—custom claims augmentation. I needed to connect to a remote data source so that I could query for some additional information about each user, and then use that information to determine what claims to augment.

As a general guideline for using data sources in custom claims providers, it is important to remember that your custom claims provider assembly is going to be kept alive in memory by the SharePoint security token service (STS) process. That makes it a lot easier to retrieve "information"—whether that is, for example, a dataset or a set of credentials—by storing it in a class-level variable so that it is available for use until the next IISReset. The limitation here is that not all SharePoint farm resources may be available to you at the time that your custom claims provider class is instantiated.

In this particular case, I wanted to retrieve data from the Secure Store Service in the constructor for my custom claims provider, and then I was going to do another operation with it; in my case I was creating a WindowsIdentity object from a domain across a one-way trust so that I could use it to create an impersonation context that had permissions to query the remote Active Directory directory service. The issue occurs whenever I try to do anything with my reference to the Secure Store Service in the constructor; it always timed out. It did not matter what method was called on the Secure Store Service, it always failed with a time-out error after 60 seconds.

The fix was simply to move the code out of the constructor. The same exact code works when invoked from my override of the FillClaimsForEntity method. It was really just luck and trial and error that I figured this out, so it seems like a good tip to share.

While we are discussing this particular problem (logging on to a remote domain and impersonating), it is worth sharing one other pattern that I gleaned from what I learned, and one other "gotcha." As described earlier, because your assembly stays loaded in the STS process, you can keep your class level variables alive. Because I do not want to have to repeatedly log on to the remote domain when I needed to query it, I created a class-level variable for my WindowsIdentity object. The pattern is as follows:

  1. Check whether I have retrieved the Secure Store Service credentials.

    • If not, execute the code that:

      1. Retrieves the credentials from the Secure Store Service.

      2. Uses the LogonUser API to log on to the remote domain by using the credentials that I got from the Secure Store Service.

      3. Instantiates my WindowsIdentity variable so that it has the credentials of the remote user.

  2. Check to see whether my WindowsIdentity variable is null.

    • If not, execute the code that:

      1. Creates a new instance of a WindowsImpersonationContext object from the WindowsIdentity.Impersonate method.

      2. Queries the remote domain.

      3. Calls the Undo method on my WindowsImpersonationContext object.

That pattern seems to work well, and is about as much performance as I can wring out of it so far. Now, here is the gotcha—you do not want to call the Impersonate method on your WindowsIdentity instance and then not call the Undo method on the resulting WindowsImpersonationContext object afterward. If you do not undo the impersonation, then, in my experience, the site will no longer render. Just add your undo call back, and everything starts working again.

I installed Active Directory Rights Management Services (AD RMS) in my environment, and then turned it on in SharePoint 2010. I enabled it in Central Administration, and then set up a policy in a document library. The first time that I tried downloading a document from an Information Rights Management (IRM) protected library, Microsoft Word 2010 first prompted me with a dialog box telling me that it would need to validate my license with my AD RMS server. It then came back and told me that it could not connect to the license server (which is just an HTTPS SOAP endpoint) and that the service might be unavailable, that I might need to configure a proxy server, and so on.

So, I tried navigating to the page that Word 2010 said it was going to in order to validate the license by pasting the URL in the browser. The page renders fine. I was not sure what was happening during this "license validation" check, so I started Fiddler to see what was going on. Of course, as soon as I did this, Word 2010 opened the document without any problem.

I suspected that something about the way Fiddler decrypts HTTPS traffic (it inserts its own Secure Sockets Layer (SSL) certificate in the channel) was a factor, but could not figure out what was wrong—after all, the site opened fine in Internet Explorer, it was using a domain-issued wildcard certificate that I have used on other servers in my farm, and so on.

After some back-and-forth with other people about things to try and look at, I followed one of their suggestions and unselected the Fiddler option to ignore certificate errors. After I did this, Word 2010 would not open the document anymore, even with Fiddler running.

In the course of trying many different things (because there was no straight-forward error description), on a whim I removed my domain wildcard certificate from the RMS HTTPS endpoint, and I issued a new certificate specifically for the fully qualified domain name of that server. I recycled the Internet Information Services (IIS) virtual server and then went back to try and download the document from SharePoint 2010. It worked. The net of this is that if you are using AD RMS with SharePoint 2010 (or any client application), I would not recommend using a wildcard certificate for the AD RMS licensing service SOAP endpoint.

There are many scenarios where you need to have a trust with the Active Directory Federation Services (AD FS) 2.0 server that SharePoint 2010 authenticates to. For example, you might have to authenticate to another identity provider, or you might want to federate multiple Active Directory forests. In this tip, I walk through how you establish trust between two AD FS 2.0 servers that are hosted in two different Active Directory forests, and how you get the claims to go across back to SharePoint 2010. I am assuming that you already added SharePoint 2010 as a trusted relying party in one of the AD FS 2.0 servers.

Start with the AD FS 2.0 server that your SharePoint site has trust with. We will call this AD FS server RP. For this exercise:

  1. In the browser, open the federationmetadata.xml file from the AD FS 2.0 server that users will be authenticating against (we will call this AD FS server IP). By default, the location is https://myIpAdfsServer/FederationMetadata/2007-06/FederationMetadata.xml. If you get an untrusted certificate error in the browser, you must add the root authority certificate for the IP AD FS server SSL to your trusted root authorities' store. This assumes that you have the same root authority certificate for both the SSL access to the IP AD FS web server and the IP AD FS token-signing certificate. If they are not the same, you must add the root certificate authority for both to the certificate store of the local RP AD FS server. Following are the steps to do so:

    1. Click through the error to view the website, which should show the XML file.

    2. Click the View Certificates icon, so that you can see the SSL certificate that is used.

    3. On the Certificate Path tab, double-click the top certificate in the chain—this is the root authority certificate.

    4. On the Details tab, click Copy to File, and then save the certificate in CER format to the local disk. You can now close all the certificate dialog boxes and the browser.

    5. Open the Certificate Microsoft Management Console (MMC) snap-in. If you do not have a shortcut for the MMC snap-in, start the MMC from the Run menu:

      1. In the Run box, type MMC.

      2. In the Console dialog box, on the File menu, click Add/Remove Snap-in.

      3. In the Add/Remove Snap-ins dialog box, add the Certificates snap-in.

      4. Select Computer account, and then click Next.

      5. Select Local computer, and then click Finish.

    6. Expand the Trusted Root Certification Authorities node, right-click the Certificates node, and then select Import. Follow the wizard to import the root authority .cer file that you exported earlier.

  2. Open the AD FS 2.0 Management application.

  3. Expand the Trust Relationships node, right-click the Claim Provider Trusts node, and then select Add Claims Provider Trust.

  4. Click Start to begin the wizard.

  5. Leave the default option selected (to import data about the claims provider published online or on a local network) and, in the text box, type the address to the FederationMetadata.xml file (https:// myIpAdfsServer/FederationMetadata/2007-06/FederationMetadata.xml by default).

  6. Click Next. If your root authority certificate is correctly installed and the name can be resolved, the wizard continues to the next step. If not, you have troubleshooting to do.

  7. Provide a Display Name and, optionally, Notes, then click Next.

  8. Review your data, and then click Next.

  9. Click Close to complete the wizard. Leave the check box selected, to open up the rules dialog box when complete.

Now, for the claims provider trust, you need to create rules to pass through all the claims that you get from the IP AD FS 2.0 server. So, in the rules dialog box, for each claim that you want to send to SharePoint 2010, do the following:

  1. Click Add Rule.

  2. In the drop-down list, select Pass Through or Filter an Incoming Claim in the Claim Rule Template, and then click Next.

  3. Provide a Claim Name—including the name of the claim that is being passed through is useful. In the Incoming Claim Type drop-down list, select the claim type that you want to pass through (for example, E-Mail Address). I usually leave the default option for Pass through all claim values selected, but if you have different business rules, select whatever is appropriate, and then click Finish. If you choose to pass through all claim values, AD FS 2.0 displays a warning dialog box.

After you add pass through claims for each claim that you need in SharePoint 2010, you can close the rules dialog box.

Now, for the last part of the RP AD FS 2.0 server configuration, you must find the SharePoint relying party. In the Edit Claim Rules dialog box, for each Pass Through claim rule that you made in the previous step, you must also add a Pass Through claim rule for the SharePoint relying party. This enables the claims to flow from the IP AD FS 2.0 server to the RP AD FS 2.0 server through the trusted claims provider, and out to SharePoint 2010 through the trusted relying party. If the claims from your IP AD FS 2.0 server are not appearing in SharePoint, these are the two locations (Pass Through claim rule and SharePoint relying party) where you should start looking.

Next we move to the IP AD FS 2.0 server. First, complete step 1(a) through step 1(f), as described earlier, to ensure that you added the root authority certificates to the IP AD FS 2.0 server:

  1. Open the AD FS 2.0 Management application.

  2. Expand the Trust Relationships node, right-click Relying Party Trusts, and then select Add Relying Party Trust.

  3. Click Start to begin the wizard.

  4. Leave the default option selected, to import data about the claims provider published online or on a local network. In the text box, type the address to the FederationMetadata.xml file (https://myRpAdfsServer/FederationMetadata/2007-06/FederationMetadata.xml by default), and then click Next. If your root authority certificate is correctly installed and the name can be resolved, the wizard continues to the next step. If not, you have troubleshooting to do.

  5. Provide a Display Name and, optionally, Notes, and then click Next.

  6. Review your data, and then click Next.

  7. Click Close to complete the wizard. Leave the check box selected to open up the rules dialog box when complete.

Because this is the AD FS IP, we must create a rule to pass along all the claims that are going to be needed by SharePoint, the same way as you do when you add SharePoint as a relying party in AD FS. Rather than walking through it in detail, I suggest that you read the AD FS end-to-end configuration posting that I made on my blog: Configuring SharePoint 2010 and AD FS v2 End to End.

Explained briefly, you want to add a rule to Send LDAP Attributes as Claims. Configure this rule the same way (select the same claims and make the same mappings) as you do when you configure SharePoint as a relying party in AD FS. That concludes the configuration that you must do on the IP AD FS.

That's it. You should now be set up to browse to your SharePoint farm and be redirected to the IP AD FS server to authenticate, while hitting your RP AD FS server coming and going. Again, remember that if your client computers do not have the root authority certificate for the IP AD FS server's website SSL certificate, you must add this certificate to your client's local trusted root authority certificate store. Otherwise, when you go to authenticate and you are redirected to the IP ADFS server's website, you get a certificate warning dialog box.

After you have this set up, if you try and authenticate as a user on IP AD FS, you may receive an error message in the browser coming from the IP AD FS, saying that some error occurred. If you look in the event log on the IP AD FS server, you may see message ID #317 in the Applications and Services Logs of the Administrator node in AD FS 2.0 that says: The following errors occurred while building the certificate chain: The revocation function was unable to check revocation for the certificate.

You will likely see this message if the token-signing certificate that is used by the RP AD FS is either self-signed or domain-issued. You can eliminate this problem by turning off certificate revocation checking for your relying party. To do so, open a Windows PowerShell window on the IP AD FS server and type the following commands:

add-pssnapin microsoft.adfs.powershell
SEt-ADFSRelyingPartyTrust -TargetName <YourRelyingPartyName> -EncryptionCertificateRevocationCheck None

You may need to restart the AD FS 2.0 service after making this change.

And that does it. It is "interesting" to boil several hours of hair-pulling frustration into a tip. I hope this helps someone, somewhere.

The following is a quick tip, to save you a little time in case you decide that you want to add more claims for your users in AD FS 2.0 and have the claims successfully consumed in SharePoint 2010. The most important thing to remember is that SharePoint supports only Security Assertion Markup Language (SAML) 1.X, so it requires that the claim type be in a very specific value.

In AD FS 2.0 you can add more claims easily by using the custom rules language that it exposes. To add more claims, do the following:

  1. In AD FS 2.0, click your SharePoint relying party.

  2. In the right action pane, click Edit Claim Rules.

  3. When the rules editor is displayed, click Add Rule, and then select Send Claims Using a Custom Rule in the drop-down list.

  4. Click Next to continue, and then you can enter a claim name and your custom claim rule by using the rules language for AD FS 2.0.

Unfortunately, the very first example rule cited on that page will not work for SharePoint because the name is not in a format that WS-Federation supports. Fortunately, Adam Conkle has written a wiki entry about the correct formats for WS-Federation: AD FS 2.0: The Admin Event Log Shows Error 111 with System.ArgumentException: ID4216. The important thing for SharePoint developers to understand is his description of the naming requirements for SAML 1.X. The following is taken from Adam's wiki (thanks Adam!):

SAML 1.1 tokens have strict URI rules, which state that the format must be namespace/name. These can be constructed many ways; following are a few common examples:

  • myOrganization/myClaimType

  • urn: myOrganization:claims/myClaimType

  • http://myOrganization/claims/myClaimType

For example, you can add a custom claim in AD FS 2.0 that goes to SharePoint 2010 with a rule that looks similar to the following:

issue(Type = "", Value = "ContosoPlayoffs2011");

The rules language in AD FS 2.0 is actually pretty interesting; there is a lot of functionality in there. And now you know what format you need your claim types to be when you send them to SharePoint 2010.

This article provides answers to some frequently asked questions about claims, certificates, and the Secure Store Service in SharePoint 2010. It also provides five tips to help solve problems that are related to configuring claims and the Secure Store Service, and points to other resources for more information.