目录
- 简介
- 创建自签名证书
- 将证书绑定到 HTTPS
- 导出自签名证书
- 在 Web 服务和 SharePoint Foundation 2010 之间建立信任关系
- 确定 SharePoint 安全令牌服务证书的指纹
- 替换 web.config 文件
- 结论
- 其他资源
本文是介绍如何通过 Microsoft Business Connectivity Services (BCS) 创建和使用声明感知 Web 服务的系列文章的第三部分(共四部分)。
- WCF:为 SharePoint 2010 Business Connectivity Services 构建 WCF Web 服务(第 1 部分,共 4 部分)
- WCF:在 WCF Web 服务内确定调用方身份(第 2 部分,共 4 部分)
- WCF:在 WCF Web 服务和 SharePoint 2010 安全令牌服务之间建立信任关系(第 3 部分,共 4 部分)(本文)
- WCF:使用启用声明的 WCF Web 服务作为 SharePoint 2010 外部内容类型(第4 部分,共 4 部分)
简介
安装的每个 Microsoft SharePoint 2010 都具有一个内置安全令牌服务 (STS)。虽然可以建立信任关系来保护不是 Microsoft SharePoint 2010 安装的一部分的令牌服务,但到目前为止,最常见的情形是您与 SharePoint STS 建立了信任关系。因此,本文重点介绍该情形。
若要按照本文中的过程操作,则必须安装两台服务器。其中一台服务器必须运行您在本系列中的前两篇文章中开发的 Windows Communication Foundation (WCF) Web 服务。另一台服务器必须安装和运行 SharePoint Foundation 2010 实例。我在新安装的 SharePoint Foundation 2010 实例上测试了这些过程。
下图演示此情形中的各种因素。用户连接到与 Business Data Connectivity (BDC) Service 对话的前端 Web 服务器。BDC 运行时调用 SharePoint STS 和 Web 服务。
图 1. Business Data Connectivity Service 概述
首先,您必须创建自签名证书。开发人员必须定期执行此活动,但当真正部署解决方案时,可使用由证书颁发机构颁发的证书。
注释: |
---|
如果您已具有证书颁发机构颁发的有效证书,则可以使用该证书,而无需创建自签名证书。
|
创建自签名证书
创建自签名证书
-
启动 Internet Information Services 管理器。(依次单击“开始”,“管理工具”,然后单击“Internet Information Services (IIS) 管理器”。)
-
在“连接”窗格中选择服务器。双击“服务器证书”。
图 2. Internet Information Services (IIS) 管理器中的服务器证书
-
单击“创建自签名证书”。下图演示如何创建自签名证书。
图 3. 从 IIS Manager 创建自签名证书
-
该向导要求您指定友好名称。为证书指定可指示该证书的源服务器的名称将非常有用。在本示例中,我将其命名为承载 Web 服务的计算机的计算机名。
图 4. 指定证书的友好名称
将证书绑定到 HTTPS
将证书绑定到 HTTPS
-
在 Information Services 管理器中,右键单击包含 Web 服务应用程序的网站,然后单击“编辑绑定”。下图演示如何配置默认网站的绑定。
图 5. 编辑默认网站的绑定
-
如果按照本系列中的过程操作,并从新安装的操作系统开始,则会看到并无 HTTPS 绑定。单击“添加”。
-
在“添加网站绑定”对话框中,从“类型”下拉列表中选择“https”。
-
接下来,选择以前创建的安全套接字层 (SSL) 证书。
图 6. 选择 SSL 证书
-
单击“视图”以查看有关该证书的详细信息。我们应特别关注“主题”属性。下图显示“主题”属性中的域名。
图 7. 主题属性中的域名
注意“主题”字段的值,因为在使用 Microsoft SharePoint Designer 2010 连接到服务时,需要使用该值。您需要该值来完成该系列中第四篇文章(WCF:使用启用声明的 WCF Web 服务作为 SharePoint 2010 外部内容类型(第4 部分,共 4 部分))中的过程。
-
单击“确定”,然后单击“关闭”。
接下来,必须在使用 Web 服务的计算机(即运行 SharePoint Foundation 2010 的服务器)和承载 Windows Communication Foundation (WCF) Web 服务的计算机之间建立信任关系。为此,可导出以前创建的证书,将其复制到使用 Web 服务的计算机,然后使用 Windows PowerShell cmdlet 导入该证书。
导出自签名证书
导出自签名证书
-
启动 Microsoft 管理控制台。(最简单的方法是在“开始”菜单搜索框中输入 mmc。)
-
在控制台中,选择“文件”,然后单击“添加/删除管理单元”。
-
在“添加或删除管理单元”对话框中的“可用的管理单元”列表中,单击“证书”。
-
单击“添加”按钮。下图显示“添加或删除管理单元”对话框。
图 8.“添加或删除管理单元”对话框
-
添加管理单元时,必须指出要为其管理证书的帐户。单击“计算机帐户”,然后单击“下一步”。
-
单击“完成”,然后单击“确定”。
-
现在,查找以前创建的证书。依次展开“证书”,“个人”,然后单击“证书”。应查找颁发给您所在的计算机的证书,以及由您所在的计算机颁发的证书,如下图所示。
图 9. 查找自签名证书
-
右键单击证书,单击“所有任务”,然后单击“导出”。这会启动“导出证书”向导。下图演示如何启动“导出证书”向导。
图 10. 导出自签名证书
-
在欢迎对话框中,单击“下一步”。
-
在下一个对话框中,选择“不,不要导出私钥”,然后单击“下一步”。
-
在下一个对话框中,默认设置是“DER 编码二进制 X.509 (.CER)”。不要更改此设置;单击“下一步”。
-
在下一个对话框中,指定证书文件的路径和文件名。在本示例中,因为计算机名为 ericwhit209,因此我将该证书命名为 ericwhit209.cer。单击“下一步”。
-
单击“完成”。向导将指示导出是否成功。
现在已导出自签名证书,必须将该证书复制到运行 SharePoint Foundation 2010 服务器的计算机,然后将其导入。
注释: |
---|
仅当使用自签名证书时,才必须执行此过程。如果您使用的是证书颁发机构颁发的证书,则不必执行此过程中的步骤。当 Business Connectivity Services 使用 HTTPS 调用 Web 服务时,此过程会启用证书验证过程。
|
注释: |
---|
通过以下两个过程,可在 SharePoint STS 和 Web 服务之间建立信任关系。
|
在 Web 服务和 SharePoint Foundation 2010 之间建立信任关系
在 Web 服务和 SharePoint Foundation 2010 之间建立信任关系
-
将证书文件从承载 Web 服务的计算机复制到承载 SharePoint 的计算机。
注释: 必须在承载 SharePoint 的计算机上执行以下步骤。 -
启动 SharePoint 2010 Management Shell。以管理员身份运行。下图演示以管理员身份运行 Management Shell。
图 11. 以管理员身份运行 Management Shell
-
将证书从 Web 服务计算机复制到服务器计算机后,将目录更改为将该证书复制到的位置。
图 12. 复制的证书
-
将证书读入 Windows PowerShell 变量,然后将该证书提交到 SharePoint 信任的根证书颁发机构。将以下内容输入 Windows PowerShell控制台,将 ericwhit209.cer 替换为在导出和复制证书时为其提供的名称。
$cert = Get-PfxCertificate ./ericwhit209.cer New-SPTrustedRootAuthority -Certificate $cert -Name ericwhit209
提交证书后,cmdlet 会输出与下图类似的内容。
图 13. SPTrustedRootAuthority cmdlet 的输出
您可以看到颁发者、证书有效范围及其他更多内容。
现在已绑定 https,可更新 web.config 以供 WCF Web 服务使用。但在更新 web.config 前,必须在承载 SharePoint 的服务器计算机上确定安全令牌服务 (STS) 证书的指纹。
确定 SharePoint 安全令牌服务证书的指纹
确定 SharePoint 安全令牌服务证书的指纹
-
在运行 SharePoint Foundation 2010 的服务器计算机上,启动 Microsoft 管理控制台,然后添加证书管理单元。
-
展开“证书”,然后展开“SharePoint”。单击“证书”节点,如下图所示。
图 14. SharePoint 安全令牌服务证书
-
该证书是颁发给安全令牌服务 (STS) 的顶级证书。双击该证书。
-
在下一步中,必须将该证书的指纹复制到剪贴板。该步骤包含一个需要格外注意的过程。如果复制文本框中的第一个可见空格,则会将不可见的字节顺序标记 (BOM) 复制到剪贴板中字符串的相应位置。必须确保选择了十六进制数字字符串,而未选择第一个字符。下图演示如何选择证书的指纹。
图 15. 选择指纹
将指纹从“证书”对话框复制到剪贴板。
-
从指纹文本中删除空格。从证书管理器复制的文本如下所示,其中使用空格隔开十六进制字节:
启动记事本,将文本粘贴到记事本,然后删除空格,以使字符串显示如下:
这是下一步中需要的指纹之一。
-
可通过尝试使用 ANSI 编码保存文件来确保您并未复制字节顺序标记。在记事本中的菜单上,单击“文件”,然后单击“另存为”,指定一个文件名,然后单击“保存”,如下图所示。
图 16. 使用 ANSI 编码保存指纹
如果您并未选择包含 BOM 的字符(这样做是正确的),则会正确保存该文件。如果错误选择了 BOM,则记事本会指出该文件包含 Unicode 格式的字符,如果将该文件另存为 ANSI 编码的文本,则这些字符会丢失。下图显示错误复制 BOM 并尝试另存为 ANSI 编码的文本时生成的错误。
图 17. 复制 BOM 时生成的错误
-
复制和保存该指纹,以便可将其粘贴到 Web 服务的 web.config 中。
替换 web.config 文件
替换 Web 服务的 web.config 文件
-
在 Visual Studio 中打开 Web 服务项目。
-
将 web.config 文件替换为以下列表的内容。在此 web.config 中,必须更新 4 个值。
<?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>
-
更新安全令牌服务 (STS) 的终结点 URL。只能更新计算机名。指定计算机名后,即会知道安全令牌服务 (STS) 的终结点 URL。
-
更新安全令牌服务 (STS) 的元数据发现 URL。对于终结点 URL,只能更新计算机名。
-
更新安全令牌服务 (STS) 的指纹以及您在上文中确定的值。
-
更新颁发者令牌的名称。该名称在颁发者名称注册机构的受信任颁发者中必须是唯一的。请使用承载 WCF Web 服务的计算机的服务器名称。
此时,已正确配置 Web 服务。在下一篇文章中,您将使用 SharePoint Designer 2010 来利用作为外部内容类型的 Web 服务。
结论
在本文中,您完成了创建声明感知 Web 服务的四个主要步骤中的第三个步骤,并通过使用 Business Connectivity Services 来利用它。您配置了 Web 服务,以便它信任安全令牌服务 (STS),并将安全令牌服务 (STS) 配置为信任 Web 服务。在下一篇文章 WCF:使用启用声明的 WCF Web 服务作为 SharePoint 2010 外部内容类型(第4 部分,共 4 部分)中,您将使用 SharePoint Designer 2010 按照相应过程从运行 Microsoft SharePoint 2010 的服务器使用启用声明的 Web 服务。