WCF: Establishing Trust Between WCF Web Services and SharePoint 2010 Security Token Service (Part 3 of 4)
Summary: Learn to authenticate users in Microsoft SharePoint Foundation 2010 in this four-part series. Enable federated HTTP binding for a web service and establish trust between the Windows Communication Foundation (WCF) web service and the SharePoint 2010security token service (STS).
Available in SharePoint Online
Applies to: Business Connectivity Services | Office 2010 | Open XML | SharePoint Designer 2010 | SharePoint Foundation 2010 | SharePoint Online | SharePoint Server 2010 | Visual Studio
Provided by: Eric White, Microsoft Corporation | Saji Varkey, Microsoft Corporation | Bin Zhang, Microsoft Corporation
Contents
Introduction
Creating Self-Signed Certificates
Binding the Certificate to HTTPS
Exporting Self-Signed Certificates
Establishing Trust between Web Services and SharePoint Foundation 2010
Determining the thumbprint of the SharePoint Security Token Service certificate
Replacing the web.config File
Conclusion
Additional Resources
This article is the third in a four-part series of articles that show how to create and consume a claims-aware web service using Microsoft Business Connectivity Services (BCS).
WCF: Building WCF Web Services for SharePoint 2010 Business Connectivity Services (Part 1 of 4)
WCF: Determining Caller Identity within WCF Web Services (Part 2 of 4)
WCF: Establishing Trust Between WCF Web Services and SharePoint 2010 Security Token Service (Part 3 of 4) (This article)
Introduction
Every Microsoft SharePoint 2010 installation has a built-in security token service (STS). Although you could establish trust relationships to security token services that are not part of a Microsoft SharePoint 2010 installation, by far the most common scenario is where you establish a trust relationship with the SharePoint STS. Therefore this article focuses on that scenario.
To follow the procedures in this article, you must have two servers set up. One of the servers must be running the Windows Communication Foundation (WCF) web service that you developed in the first two articles in this series. The other server must have an installed, running instance of SharePoint Foundation 2010. I tested these procedures on a newly installed instance of SharePoint Foundation 2010.
The following diagram shows the various actors in this scenario. The user connects to the front-end web server, which talks to the Business Data Connectivity (BDC) service. The BDC runtime calls to SharePoint STS and the web service.
Figure 1. Overview of Business Data Connectivity service
First, you must create a self-signed certificate. This is an activity that you regularly do as a developer, but when you actually deploy the solution, you use a certificate issued by a certification authority.
Note
If you already have a valid certificate issued by a certification authority, you can use that certificate instead of creating a self-signed certificate.
Creating Self-Signed Certificates
To create a self-signed certificate
Start Internet Information Services Manager. (Click Start, click Administrative Tools, and then click Internet Information Services (IIS) Manager.)
Select the server in the Connections pane. Double-click Server Certificates.
Figure 2. Server certificates in Internet Information Services (IIS) Manager
Click Create Self-Signed Certificate. The following figure shows how to create a self-signed certificate.
Figure 3. Creating self-signed certificates from the IIS Manager
The wizard asks you to specify a friendly name. It is useful to give it a name that indicates the server the certificate came from. In my case, I gave it the computer name for the computer that the web service is hosted on.
Figure 4. Specifying the friendly name of the certificate
Binding the Certificate to HTTPS
To bind the certificate to HTTPS
In Information Services Manager, right-click the site that contains the web service application, and then click Edit Bindings. The following figure shows how to configure the bindings for the default web site.
Figure 5. Edit the bindings for the default web site
If you followed the procedures in this series, and started with a newly installed operating system, you see that there is no HTTPS binding. Click Add.
In the Add Site Binding dialog box, select https from the Type drop-down list.
Next, select the secure sockets layer (SSL) certificate that you previously created.
Figure 6. Select the SSL certificate
Click View to view details about the certificate. In particular, we are interested in the Subject property. The following figure shows the domain name in the Subject property.
Figure 7. Domain name in the subject property
Note the value of the Subject field, as you require that value when connecting to the service by using Microsoft SharePoint Designer 2010. You need this value to complete the process in the fourth article in this series, WCF: Consuming Claims-Enabled WCF Web Services as SharePoint 2010 External Content Types (Part 4 of 4)
Click OK, and then click Close.
Next, you must establish trust between the computer that is using the web service (the server that is running SharePoint Foundation 2010), and the computer that is hosting the Windows Communication Foundation (WCF) web service. To do this, you export the certificate that you previously created, copy it to the computer that is using the web service, and import the certificate by using a Windows PowerShell cmdlet.
Exporting Self-Signed Certificates
To export the Self-Signed Certificate
Start Microsoft Management Console. (The easiest way is to enter mmc into the Start menu search box.)
In the console, select File, and then click Add/Remove Snap-in.
In the Add or Remove Snap-ins dialog box, in the Available snap-ins list, click Certificates.
Click the Add button. The following figure shows the Add or Remove Snap-Ins dialog box.
Figure 8. Add or Remove Snap-Ins dialog box
When adding the snap-in, you must indicate the account for which you are managing certificates. Click Computer Account, and then click Next.
Click Finish, and then click OK.
Now find the certificate that you previously created. Expand Certificates, expand Personal, and then click Certificates. You should find one certificate that is issued to the computer that you are on. and a certificate issued by the computer that you are on as shown in the following figure.
Figure 9. Finding the self-signed certificate
Right-click the certificate, click All Tasks, and then click Export. This starts the Export Certificate wizard. The following figure shows how to start the Export Certificate wizard.
Figure 10. Exporting the self-signed certificate
On the Welcome dialog, click Next.
In the next dialog, select, No, do not export the private key, and then click Next.
In the next dialog, the default setting is DER encoded binary X.509 (.CER). Do not change the setting; click Next.
In the next dialog, specify the path and file name for the certificate file. In my case, because the computer name is ericwhit209, I named the certificate ericwhit209.cer. Click Next.
Click Finish. The wizard indicates whether the export was successful.
Now that you exported the self-signed certificate, you must copy this certificate to the computer that is running SharePoint Foundation 2010 server and import it.
Note
You have to perform this procedure only if you are using a self-signed certificate. If you are using a certificate that is issued by certification authority, you do not have to follow the steps in this procedure. This procedure enables certificate validation when Business Connectivity Services call to the web service by using HTTPS.
Note
The following two procedures establish trust between the SharePoint STS and the web service.
Establishing Trust between Web Services and SharePoint Foundation 2010
To establish trust between the web service and SharePoint Foundation 2010
Copy the certificate file from the computer that hosts the web service to the computer that hosts SharePoint.
Note
The following steps must be performed on the computer that hosts SharePoint.
Start a SharePoint 2010 Management Shell. Run as administrator. The following figure shows running the management shell as administrator.
Figure 11. Run the management shell as administrator
Change directory to where you copied the certificate when you copied it from the web service computer to the server computer.
Figure 12. Copied certificate
Read the certificate into a Windows PowerShell variable, and then submit the certificate to the SharePoint trusted root authority. Enter the following into the Windows PowerShellconsole, replacing ericwhit209.cer with the name that you gave the certificate when you exported it and copied it.
$cert = Get-PfxCertificate .\ericwhit209.cer New-SPTrustedRootAuthority -Certificate $cert -Name ericwhit209
After the certificate is submitted, the cmdlet output something resembling the following figure.
Figure 13. Output of the SPTrustedRootAuthority cmdlet
You can see the issuer, its range of validity, and more.
Now that https is bound, you can update the web.config for the WCF web service to use it. But before you can update the web.config, you must determine the thumbprint of the security token service (STS) certificate on the server computer that hosts SharePoint.
Determining the thumbprint of the SharePoint Security Token Service certificate
To determine the thumbprint of the SharePoint Security Token Service certificate
On the server computer that is running SharePoint Foundation 2010, start Microsoft Management Console, and add the certificate snap-in.
Expand Certificates, and then expand SharePoint. Click the Certificates node as shown in the following figure.
Figure 14. SharePoint security token service certificate
The certificate is the top one that is issued tosecurity token service (STS). Double-click the certificate.
In the next step, you must copy the thumbprint of the certificate to the clipboard. There is a tricky part to this step. If you copy the first apparent space in the text box, you will be copying an invisible byte order mark (BOM) to the clipboard at that location in the string. You must make sure that you select the string of hexadecimal digits without selecting that first character. The following figure shows how to select the thumb print of the certificate.
Figure 15. Selecting the thumb print
Copy the thumbprint from the Certificate dialog box to the clipboard.
Remove the spaces from the text of the thumbprint. The text as copied from the Certificate manager is as follows, with spaces separating the hexadecimal bytes:
dd be 98 f4 c2 db e6 d7 8c ec 14 d0 d0 0a b8 90 d1 53 08 f6
Start Notepad, paste the text into Notepad, and remove the spaces so that the string is as follows:
ddbe98f4c2dbe6d78cec14d0d00ab890d15308f6
This is one of the thumbprints that you need in the following step.
You can validate that you did not copy the byte order mark by trying to save the file with the ANSI encoding. In Notepad, on the menu, click File, then click Save As, specify a file name, and then click Save as show in the following figure.
Figure 16. Save the thumbprint with ANSI encoding
If you correctly did not select the character that contains the BOM, then the file saves correctly. If you incorrectly selected the BOM, Notepad indicates that the file contains characters in Unicode format that will be lost if you save the file as ANSI-encoded text. The following figure shows the error that results if you incorrectly copy the BOM and attempt to save as ANSI-encoded text.
Figure 17. Error resulting from copying BOM
Copy and save this thumbprint so that you can paste it into the web.config for the web service.
Replacing the web.config File
To replace the web.config file for the web service
Open the project for the web service in Visual Studio.
Replace the web.config file with the contents of the following listing. There are four values that you must update in this web.config.
<?xml version="1.0"?> <configuration> <configSections> <section name="microsoft.identityModel" type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> </configSections> <system.serviceModel> <diagnostics> <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtTransportLevel="true" /> </diagnostics> <services> <service behaviorConfiguration="CustomersService.Service1Behavior" name="CustomersService.Customers"> <endpoint address="" binding="ws2007FederationHttpBinding" contract="CustomersService.ICustomers" bindingConfiguration="Customers_ws2007FedHttpBinding"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <behaviors> <serviceBehaviors> <behavior name="CustomersService.Service1Behavior"> <federatedServiceHostConfiguration name="CustomersService.Customers"/> <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> <serviceMetadata httpGetEnabled="true"/> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> <bindings> <customBinding> <binding name="AsymmetricWindowsHttpBinding"> <security defaultAlgorithmSuite="Basic256Sha256" authenticationMode="SspiNegotiated" requireDerivedKeys="true" securityHeaderLayout="Strict" includeTimestamp="true" keyEntropyMode="CombinedEntropy" messageProtectionOrder="SignBeforeEncryptAndEncryptSignature" messageSecurityVersion="WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10" requireSecurityContextCancellation="true" requireSignatureConfirmation="false"> <localClientSettings cacheCookies="true" detectReplays="true" replayCacheSize="900000" maxClockSkew="00:05:00" maxCookieCachingTime="Infinite" replayWindow="00:05:00" sessionKeyRenewalInterval="10:00:00" sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="true" timestampValidityDuration="00:05:00" cookieRenewalThresholdPercentage="60" /> <localServiceSettings detectReplays="true" issuedCookieLifetime="10:00:00" maxStatefulNegotiations="128" replayCacheSize="900000" maxClockSkew="00:05:00" negotiationTimeout="00:01:00" replayWindow="00:05:00" inactivityTimeout="00:02:00" sessionKeyRenewalInterval="15:00:00" sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="true" maxPendingSessions="128" maxCachedCookies="1000" timestampValidityDuration="00:05:00" /> <secureConversationBootstrap /> </security> <binaryMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16" maxSessionSize="2048"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> </binaryMessageEncoding> <httpTransport manualAddressing="false" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous" bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard" keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous" realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false" useDefaultWebProxy="true" /> </binding> <binding name="AsymmetricCookieHttpsBinding"> <security authenticationMode="IssuedTokenOverTransport" defaultAlgorithmSuite="Basic256Sha256" messageSecurityVersion="WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12"/> <binaryMessageEncoding> <readerQuotas maxStringContentLength="1048576" maxArrayLength="2097152"/> </binaryMessageEncoding> <httpsTransport maxReceivedMessageSize="2162688" authenticationScheme="Anonymous" useDefaultWebProxy="false"/> </binding> </customBinding> <ws2007FederationHttpBinding> <binding name="Customers_ws2007FedHttpBinding"> <security mode="TransportWithMessageCredential"> <message issuedKeyType="AsymmetricKey"> <!-- UPDATE: the URL for the SharePoint security service --> <issuer address="http:// ericwhit210/_vti_bin/sts/spsecuritytokenservice.svc/windows" binding="customBinding" bindingConfiguration="AsymmetricWindowsHttpBinding"/> <!-- UPDATE: the metadata URL for the SharePoint security service --> <issuerMetadata address="http:// ericwhit210/_vti_bin/sts/spsecuritytokenservice.svc?wsdl"/> </message> </security> </binding> </ws2007FederationHttpBinding> </bindings> <extensions> <behaviorExtensions> <add name="federatedServiceHostConfiguration" type="Microsoft.IdentityModel.Configuration.ConfigureServiceHostBehaviorExtensionElement, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> </behaviorExtensions> </extensions> </system.serviceModel> <microsoft.identityModel> <service name="CustomersService.Customers"> <certificateValidation certificateValidationMode="None"/> <audienceUris mode="Never"/> <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"> <trustedIssuers> <!-- UPDATE: The thumbprint that was issued by SharePoint Security Token Service --> <!-- UPDATE: The name of the issuer token --> <add thumbprint="ddbe98f4c2dbe6d78cec14d0d00ab890d15308f6" name="ericwhit210"/> </trustedIssuers> </issuerNameRegistry> </service> </microsoft.identityModel> </configuration>
Update the endpoint URL for the security token service (STS). You must update only the computer name. Given the computer name, the endpoint URL for the security token service (STS) is well-known.
Update the metadata discovery URL for the security token service (STS). As with the endpoint URL, you must update only the computer name.
Update the thumbprint for the security token service (STS) together with the value that you determined earlier in this article.
Update the name of the issuer token. This name must be unique among the trusted issuers in the issuer name registry. Use the server name of the computer that is hosting the WCF web service.
At this point, the web service is configured correctly. In the next article, you use SharePoint Designer 2010 to consume the web service as an external content type.
Conclusion
In this article, you completed the third of four major steps towards creating a claims-aware web service, and using it by using Business Connectivity Services. You configured the web service so that it trusts the security token service (STS) and you configured the security token service (STS)to trust the web service. In the next article, WCF: Consuming Claims-Enabled WCF Web Services as SharePoint 2010 External Content Types (Part 4 of 4), you follow a procedure to consume the claims-enabled web service from a server running Microsoft SharePoint 2010 by using SharePoint Designer 2010.
Additional Resources
Developer Center: SharePoint Developer Center
Blog: Eric White's Blog
Download: Microsoft .NET Framework 3.0 Redistributable Package
Download: Installing IIS