How to make use of a custom IP-STS with SharePoint 2010? (Part 2)

ID4014: A SecurityTokenHandler is not registered to read security token ('EncryptedData', 'https://www.w3.org/2001/04/xmlenc#').

Here comes the answer of the little quiz in the end of Part 1.

When I clicked SimplePassiveSTS, I was redirected to the sign-in page of my STS, which was what I want.

image

But when I signed in and was redirected back to the SharePoint site, I saw what I didn’t want. It ended up with an exception of WIF, ID4014: A SecurityTokenHandler is not registered to read security token ('EncryptedData', 'https://www.w3.org/2001/04/xmlenc#').

image

From the description of the exception, it looks like SharePoint does not know how to handle the security token sent from my STS because of no corresponding SecurityTokenHandler registered. So what SecurityTokenHandlers does SharePoint load by default?

By examining the web.config of the web app and debugging into the process, the following 3 SecurityTokenHandlers were loaded by default:

  •  Microsoft.IdentityModel.Tokens.X509SecurityTokenHandler
    
  •  Microsoft.SharePoint.IdentityModel.SPSaml11SecurityTokenHandler
    
  •  Microsoft.SharePoint.IdentityModel.SPTokenCache
    

But the security token issued by Asp.Net STS was generated by Microsoft.IdentityModel.Tokens.Saml11.Saml11SecurityTokenHandler and encrypted by Microsoft.IdentityModel.Tokens.EncryptedSecurityTokenHandler. By consulting other colleagues, it looks like SharePoint 2010 cannot handle the encrypted security token by default.

A simple solution: stop encrypting.

To verify whether the exception ID4014 was caused by the encrypted security token, a simple way is to stop encrypting the token in the STS. In Asp.Net STS, just leaving the value of the following app setting empty will stop encrypting the token.

 <add key="EncryptingCertificateName" value=""/>

This setting is handled in GetScope function of the STS. If it is empty, scope.TokenEncryptionRequired will be set to false. Hence, the token will not be encrypted anymore. 

After stopping encrypting, I could see the access denied page of SharePoint after I was redirected back from the STS site. It was expected because I didn’t give the user identity from the STS any permission to the site yet.

Another solution: making SharePoint be able to handle encrypted security tokens.

Let us go one step further. What if a custom STS has to send an encrypted security token?

According to my testing, by adding the following settings in the web.config of the web app, we can make SharePoint be able to handle an encrypted token.

  • Add EncryptedSecurityTokenHandler:
 <add type="Microsoft.IdentityModel.Tokens.EncryptedSecurityTokenHandler, 
Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

  • Add the encrypting certificate information:
     <serviceCertificate>
      <certificateReference x509FindType="FindByThumbprint" 
                            findValue="2E00D604A5DA08B2C212B0533D38F4646F314255" 
                            storeLocation="LocalMachine" storeName="My"/>
    </serviceCertificate>

  • Export the encrypting cert from the STS server and import it to SharePoint.

For testing purpose, this way works. But if you want to use this way in the production, I think the good practice is to create an encrypting cert for SharePoint to decrypt security tokens and make use of this cert in the STS to encrypt tokens. In this way,  the STS will be able to choose using different encrypting cert for different Relying Party.

Summary

After finishing the above configuration, I can now add users from the STS to the SharePoint site. The CheckName function does not work because I didn’t implement a custom claim provider to handle it. For how to create a custom claim provider, please refer to the series by Steve Peschka.

The Select People and Groups dialog box works well.

image

And here comes a page with user accounts from Windows Auth, Form based auth and Trusted STS.

image

-- The End.