hoetz hoetz - 3 months ago 32x
Javascript Question

How to call external ADFS secured WCF Service within Sharepoint via Javascript in an ADFS environment?

Previously on our little Sharepoint environment: We used integrated windows authentication for everything. On some of our sharepoint sites we integrated some custom javascript application logic that was calling a non-Sharepoint WCF service, which was also secured by windows integrated authentication in IIS. It just worked, since the windows identity of the current Sharepoint User was passed down to the javascript AJAX request and on to the WCF service. The WCF service used the identity information to perform some logic and returned the call.

Then we set up Sharepoint with ADFS 3.0 which broke our javascript application code since windows integrated auth was no longer working. My question: What is the proper way to fix this? It's clear that we have to modify the external WCF service to support ADFS claims based auth. We even thought about migrating the WCF service to a .NET web api with ActiveDirectoryFederationServices BearerAuthentication.

But on the javascript side, how to call that service with the current logged on user? I understand that Sharepoint is keeping a "FedAuth" cookie with information about the current user. Can I use that token for the external web service? Any help is appreciated.


UPDATE: This did NOT work since the FedAuth cookie is HttpOnly protected and can not be accessed in javscript. So we dumped the entire idea and created a proxy webservice directly hosted in Sharepoint. Looks like this is working, but it is ugly...

This is how we solved it:

We looked at the source code of the Sharepoint STS, especially at the point where they create the FedAuth cookies and create the signature for the tokens. You can find this in the SPSessionSecurityTokenCookieValue class in the dll Microsoft.Sharepoint.IdentityModel.

//excerpt from the ValidateSignature method
RSACryptoServiceProvider key = (RSACryptoServiceProvider) SPSecurityTokenServiceManager.Local.LocalLoginProvider.SigningCertificate.PublicKey.Key;
CspParameters parameters = new CspParameters {
    ProviderType = 0x18,
    KeyNumber = (int) key.CspKeyContainerInfo.KeyNumber
if (key.CspKeyContainerInfo.MachineKeyStore)
    parameters.Flags = CspProviderFlags.UseMachineKeyStore;
using (RSACryptoServiceProvider provider2 = new RSACryptoServiceProvider(0x800, parameters))
    string s = this.BuildValueToSign(options);
    byte[] buffer = Convert.FromBase64String(signature);
    flag = provider2.VerifyData(this.m_EncodingScheme.GetBytes(s), this.m_SigningScheme, buffer);

We replicated this method in our WCF service and can now validate the values of a FedAuth cookie. Of course, you need to have the same certificate that Sharepoint uses for its Token Service (extract it via MMC, for example).

Now we are able to call the WCF service via javascript, pass the values from the user's current FedAuth cookie and confirm the identity of a user by validating the signature of the cookie. Then we can safely work with the UserKey/UserName values of the cookie in our application logic.