托管 HTTPS 上的 WCF 服务





5.00/5 (3投票s)
一个自托管 HTTPS 上的 WCF 服务,带事务的示例。
引言
本文提供了一个在 HTTPS 上自托管 WCF 服务(带事务)的示例。文章介绍了如何创建自签名证书、如何将其绑定到端口、如何编辑配置文件以及如何运行服务和客户端。WCF 服务和部分配置来自 "Self hosted WCF https works only when IIS has a site w https binding" 这篇博客文章,作者是 Bill at Cape Cod。
背景
要使 WCF 服务使用 SSL,必须将证书绑定到 WCF 服务运行所在的端口。在生产环境中,必须安装有效的证书。在开发环境中,可以创建自签名证书。本文介绍了三种创建和绑定自签名证书的方法:
- 使用 IIS 管理器
- 使用命令行工具 makecert 和 netsh http。但是,
makecert
已弃用。 - 使用提供的
CreateCert.bat
,它使用了 makecert、certutil 和 netsh http。
使用 IIS
创建证书
- 例如,通过开始/运行/inetmgr.exe 启动IIS 管理器。
- 选择顶部节点(计算机名称)。
- 双击服务器证书图标。
- 单击创建自签名证书链接。
- 为证书指定一个友好名称,例如IIS 自签名。
- 证书已添加到证书列表中。
- 选择默认网站节点,然后单击绑定链接。
- 将
端口
设置为44400
,选择SSL 证书
为 IIS 自签名,然后单击确定。 - 您可以使用以下命令检查证书是否已绑定到端口
44400
。netsh http show sslcert ipport=0.0.0.0:44400
使用 makecert
和 netsh http
创建证书
- 检查端口
44400
是否已注册证书。netsh http show sslcert ipport=0.0.0.0:44400
- 如果证书已存在,请使用以下命令删除它:
netsh http delete sslcert ipport=0.0.0.0:44400
- 为
localhost
创建证书。"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\x64\makecert" -ss My -sr LocalMachine -n CN=localhost -r
这将创建localhost
证书,您可以在证书管理单元/证书(本地计算机)/个人/证书中看到它。 - 可以使用以下方法查看证书管理单元:开始/运行/mmc/文件/添加/删除管理单元.../证书/添加/计算机帐户/下一步/本地计算机/完成
- 使证书受信任。在证书管理单元中进行复制粘贴:从个人/证书/localhost 复制到受信任的发布者/证书。
- 将证书的指纹复制到剪贴板:双击个人/证书/localhost,然后选择详细信息选项卡,单击指纹字段,选择文本框中的文本,然后按 Ctrl+C。
- 将证书添加到端口。
netsh http add sslcert ipport=0.0.0.0:44400 certhash=[certificate thumbprint] appid={12345678-1234-1234-1234-123456789012}
appid
似乎不起作用。 - 您可以使用以下命令检查证书是否已绑定到端口
44400
。netsh http show sslcert ipport=0.0.0.0:44400
使用 CreateCert.bat
创建证书
提供的 CreateCert.bat 在个人存储和 c:\localhost.cer
文件中创建自签名证书,将 c:\localhost.cer
导入受信任的发布者存储,使用 certutil
查找指纹,并将该证书与端口 44400
注册。
- 以管理员身份运行 CreateCert.bat。输出将与以下内容类似:
C:\Windows\system32>"C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\makecert" -r -sk COMPUTER1 -sr LocalMachine -ss My -n CN=COMPUTER1,CN=localhost,CN=COMPUTER1 c:\localhost.cer Succeeded C:\Windows\system32>certutil -addstore TrustedPeople c:\localhost.cer TrustedPeople "Trusted People" Signature matches Public Key Certificate "COMPUTER1" added to store. CertUtil: -addstore command completed successfully. C:\Windows\system32>del c:\localhost.cer Created certificate with thumbprint=fa5ee6c56c066a5349ba64245e09580996ec5d56 C:\Windows\system32>netsh http delete sslcert ipport=0.0.0.0:44400 SSL Certificate deletion failed, Error: 2 The system cannot find the file specified. C:\Windows\system32>netsh http add sslcert ipport=0.0.0.0:44400 certhash=fa5ee6c56c066a5349ba64245e09580996ec5d56 appid={12345678-1234-1234-1234-123456789012} SSL Certificate successfully added C:\Windows\system32>pause Press any key to continue . . .
- 不要在意错误。
SSL Certificate deletion failed, Error: 2
此命令会删除端口 44400 的任何证书,如果该端口没有绑定任何证书,则会失败。 - 您可以使用以下命令检查端口 44400 是否已绑定到证书。
netsh http show sslcert ipport=0.0.0.0:44400
这应该会产生类似以下内容的输出:SSL Certificate bindings: ------------------------- IP:port : 0.0.0.0:44400 Certificate Hash : 022d408a952cbdd44ad0668f85254001510f4ee8 Application ID : {12345678-1234-1234-1234-123456789012} Certificate Store Name : (null) Verify Client Certificate Revocation : Enabled Verify Revocation Using Cached Client Certificate Only : Disabled Usage Check : Enabled Revocation Freshness Time : 0 URL Retrieval Timeout : 0 Ctl Identifier : (null) Ctl Store Name : (null) DS Mapper Usage : Disabled Negotiate Client Certificate : Disabled Reject Connections : Disabled
Using the Code
解决方案包含两个项目
WCFService
:托管 WCF 服务的控制台应用程序。WCFClient
:调用 WCF 服务的控制台应用程序。
该服务仅实现一个方法:
<ServiceContract()>
Interface ITestService
<OperationContract()>
<TransactionFlow(TransactionFlowOption.Mandatory)>
Function GetResult() As String
End Interface
<ServiceBehavior(TransactionIsolationLevel:=
System.Transactions.IsolationLevel.Serializable,
TransactionTimeout:="00:00:30",
ReleaseServiceInstanceOnTransactionComplete:=False,
TransactionAutoCompleteOnSessionClose:=False,
IncludeExceptionDetailInFaults:=True)>
Public Class TestService
Implements ITestService
<OperationBehavior(TransactionScopeRequired:=True, TransactionAutoComplete:=True)>
Public Function GetResult() As String Implements ITestService.GetResult
Return String.Format("Hello, busy World. {0}", DateTime.Now.ToShortTimeString())
End Function
End Class
客户端只调用一次服务。
Sub Main()
Try
Using tx As New TransactionScope()
Dim client = New ServiceReference1.TestServiceClient
Dim result = client.GetResult
client.Close()
Console.WriteLine(result)
tx.Complete()
End Using
Catch ex As Exception
Console.WriteLine(ex.ToString)
End Try
Console.ReadKey()
End Sub
WCFService
的地址是 https://computer1.domain1.com:44400
,并且已在 WCFClient
和 WCFService
的 app.config 文件中注册。您需要将其更改为证书管理单元中显示的地址。
现在,一切都应该配置好了。进行测试:
- 生成解决方案。
- 启动WCFService\bin\Debug\WCFService.exe。您可能需要以管理员身份运行它。
- 启动WCFClient\bin\Debug\WCFClient.exe。您可能需要以管理员身份运行它。如果一切顺利,将显示以下内容:
历史
- 带事务和 SSL 的 WCF 服务
- 添加了 CreateCert.bat,它使用
makecert
、certutil
和netsh http sslcert
创建并注册证书。