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).

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

SharePoint BDC Overview

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

  1. Start Internet Information Services Manager. (Click Start, click Administrative Tools, and then click Internet Information Services (IIS) Manager.)

  2. Select the server in the Connections pane. Double-click Server Certificates.

    Figure 2. Server certificates in Internet Information Services (IIS) Manager

    Server Certificates from within IIS

  3. 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

    Creating a self-signed certificate

  4. 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

    Specifying the friendly name of the certificate

Binding the Certificate to HTTPS

To bind the certificate to HTTPS

  1. 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

    Edit the bindings for the default Web site

  2. 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.

  3. In the Add Site Binding dialog box, select https from the Type drop-down list.

  4. Next, select the secure sockets layer (SSL) certificate that you previously created.

    Figure 6. Select the SSL certificate

    Select the SSL certificate

  5. 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 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)

  6. 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

  1. Start Microsoft Management Console. (The easiest way is to enter mmc into the Start menu search box.)

  2. In the console, select File, and then click Add/Remove Snap-in.

  3. In the Add or Remove Snap-ins dialog box, in the Available snap-ins list, click Certificates.

  4. 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

    Add or Remove Snap-Ins dialog box

  5. When adding the snap-in, you must indicate the account for which you are managing certificates. Click Computer Account, and then click Next.

  6. Click Finish, and then click OK.

  7. 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

    Finding the self-signed certificate

  8. 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

    Exporting the self-signed certificate

  9. On the Welcome dialog, click Next.

  10. In the next dialog, select, No, do not export the private key, and then click Next.

  11. In the next dialog, the default setting is DER encoded binary X.509 (.CER). Do not change the setting; click Next.

  12. 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.

  13. 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

  1. 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.

  2. 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

    Run the management shell as administrator

  3. 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

    The copied certificate

  4. 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

    Output of the New-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

  1. On the server computer that is running SharePoint Foundation 2010, start Microsoft Management Console, and add the certificate snap-in.

  2. Expand Certificates, and then expand SharePoint. Click the Certificates node as shown in the following figure.

    Figure 14. SharePoint security token service certificate

    The SharePoint Security Token Service certificate

  3. The certificate is the top one that is issued tosecurity token service (STS). Double-click the certificate.

  4. 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

    Selecting the thumb print

    Copy the thumbprint from the Certificate dialog box to the clipboard.

  5. 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.

  6. 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

    Saving 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

    Error resulting from copying BOM

  7. 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

  1. Open the project for the web service in Visual Studio.

  2. 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>
    
  3. 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.

  4. Update the metadata discovery URL for the security token service (STS). As with the endpoint URL, you must update only the computer name.

  5. Update the thumbprint for the security token service (STS) together with the value that you determined earlier in this article.

  6. 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