在 Windows 上配置 SSL 和客户端证书验证






4.72/5 (13投票s)
Windows 环境中 SSL 和客户端证书验证的基本配置。
引言
在本文中,我们将探讨如何在Windows环境中实现SSL和客户端证书。然而,即使您不属于微软世界,本文也将为您提供一些基于证书安全的核心概念的深入见解。
我非常希望能收到您的反馈和(如有的话)更正。
背景
如果结合我之前的文章(此处)阅读本文,您将获得足够的背景知识以开始。但是,如果您已经对SSL有基本了解,则可以安全地跳过阅读它。
目录
我们将讨论以下主题
- 配置SSL
- 配置IIS以使用SSL
- 在自托管应用程序中配置SSL
- 使用客户端证书进行客户端身份验证
- CRL、CTL和证书存储
- 配置IIS进行客户端证书验证
- 在代码中访问和验证客户端证书 (.NET)
- WCF中的客户端证书验证
配置SSL
在套接字上配置SSL
.NET Framework提供了SslStream
类,该类提供了一个流,用于使用SSL对服务器和客户端进行身份验证的客户端-服务器通信。更多详细信息和代码可以在此处找到。您会注意到,在这种情况下,由于我们在套接字编程中处理传输层,因此必须在代码中手动完成一些SSL配置。请注意,我们不在这里谈论HTTPS,而是SSL over sockets。
在Web应用程序上配置HTTPS(通过SSL)
设置HTTPS的数字证书要求
正如我在之前的文章中提到的,HTTPS的核心是数字证书和PKI。它可以通过任何利用可靠流传输协议(TCP)的网络流量使用。HTTPS是SSL最流行的实现之一。服务器通过SSL进行“识别”和流量加密。HTTPS如何“识别”服务器?通过服务器使用的证书的“颁发给”属性。
历史上,证书的“颁发给”属性通常是网站地址(例如,“blah.com”)。然后可以将其分配给一个IP地址和端口。因此,当操作系统接收到HTTPS流量时,它(http.sys/IIS使用底层Schannel SSP)可以选择网站相关的证书并使用其私钥解密流量。请记住,对于操作系统来说,这种加密的原始HTTPS流量唯一“可见”的部分是IP地址和端口号(这随着TLS中SNI的引入而改变,我们稍后会讨论)。这曾经导致在同一IP地址和端口(80)上托管多个网站时出现重大问题。请Google“SSL的鸡和蛋问题”以了解更多信息。
然而,证书的“颁发给”属性现在可以包含通配符,以反映其与域的关联。例如,*.blah.com 可以用于在 www.one.blah.com 和 www.two.blah.com 上应用 https。这仍然不是最佳的,因为可能存在(如在网络托管公司中)使用单个证书用于具有不同域名的多个站点的要求。
然后出现了多域、主题备用名称 (SAN) 证书。这些证书在“主题备用名称”字段中包含DNS名称列表。因此,操作系统现在可以使用此类证书解密HTTPS流量,并找出主机头地址以进行进一步处理。另一方面,客户端也可以积极验证服务器是否在主题备用名称列表中。然而,这再次不是最佳解决方案,因为每次需要更改(例如,删除/更改SAN列表中的一个条目)时,都必须撤销证书,并需要由CA颁发包含更改的新证书。
随着TLS的出现,出现了一个名为“服务器名称指示”(SNI)的扩展。SNI是https流量的附加可见部分,它包含服务器可以用于选择正确证书进行解密的主机头信息。但是,请记住,由于SSL/TLS依赖于服务器和客户端,因此双方在协议栈的任何进步方面都应该保持一致。Windows XP上的IE不支持TLS,因此不支持SNI。
在IIS托管网站上配置https
在IIS上,配置SSL(用于网站/Web Api/Web 服务)的步骤相对简单。我们假设您有一个有效的数字证书用于SSL。此类证书要么由您的本地CA颁发,要么由知名的外部CA提供给您。我们假设证书已正确安装在计算机的个人证书存储中。
我们将在这里讨论三种场景(可能还有很多其他场景)
场景1:托管地址为“test.dummyblah.com”的网站,并且我们服务器上安装了一个服务器证书,其“颁发给”属性设置为“*.dummyblah.com”。
这是组织托管多个网站(具有相同域名)的常见场景。
设置SSL的第一步是为HTTPS创建“站点绑定”。请参考下图;您将看到如何使用通配符SSL证书创建新的HTTPS绑定。请记住,“编辑站点绑定”窗口中的“主机名”字段仅在使用的证书是通配符证书时才有意义。因此,仅当在“SSL证书”下拉列表中选择了此类证书时,此字段才启用。
但是,该站点仍然对HTTP请求开放(存在HTTP绑定)。如果我们要限制该站点只响应HTTPS请求,则必须从该站点的“SSL设置”中进行设置。
除此之外,还需要一些步骤来将用户从HTTP重定向到HTTPS(可能是通过一些URL重写规则或HSTS头)。
场景2:在共享主机提供商(GoDaddy、Winhost等)服务器上托管HTTPS网站
这将取决于托管提供商是否具有SNI功能。如果是,您将不需要将您的网站托管在专用IP上(还记得鸡和蛋问题吗?),这通常更昂贵。托管提供商通常提供自助服务网站(例如CPANEL),您可以使用它购买并将证书链接到您的网站。
场景3:在开发机器的本地IIS上托管HTTPS网站
您(作为开发人员)可能希望在您的计算机(例如运行IIS 7)上托管您的网站/Web API,并在开发阶段使用HTTPS。为此,您将需要一个仅在您自己的机器上有效的证书。获得此类证书最简单的方法是让IIS为您生成它。如果您在IIS管理控制台中单击服务器名称(顶层),您将看到一个“服务器证书”操作按钮。打开它将允许您创建自签名证书。这将生成一个自签名服务器证书并将其安装到您本地计算机的个人证书存储中。
然后,您可以使用此证书为您的网站创建HTTPS绑定。唯一的缺陷是,您会在浏览器中看到错误消息,您必须忽略它们,因为自签名证书的“颁发给”属性设置为机器名而不是网站名(localhost)。
请注意,在我的示例中,我没有使用标准端口号(HTTP为80,HTTPS为443),而是分别使用了端口号888和444,因为我可能在我的开发PC上托管多个网站。或者,我可以使用标准端口并在IIS和“hosts”文件(位于{WIN_DIR}\System32\drivers\etc)中配置主机头来托管多个HTTP/HTTPS网站。
在您的开发机器上,您可以使用 makecert.exe 生成和使用测试证书,如此链接中所述。
场景4:运行Visual Studio的开发计算机
这种情况最简单。使用Visual Studio的精髓在于它本身负责处理许多开发人员任务。例如,当您安装Visual Studio时,它会生成并安装一个名为“IIS Express开发证书”的服务器证书,其“颁发给”字段设置为“localhost”。(或者,如果您想手动执行相同的操作——不使用VS——您可能需要使用一些证书生成实用程序,如Makecert等,来生成此类证书。)
现在,无论何时您想在网站上启用SSL,只需从网站/Web API项目的“属性”窗口中启用它即可。
在自托管(OWIN/Katana)网站上配置https
当使用Katana(OWIN的微软实现)提供的服务自托管网站时,您显然无法获得IIS提供的良好功能。请记住,Katana本质上使用“HttpListener
”类,该类又利用Windows OS提供的内核模式“http.sys
”驱动程序。因此,如果我们要通过自托管站点配置HTTPS,我们就必须在OS级别进行配置。
在操作系统级别配置SSL的一种常见方法是使用强大的“netsh
”命令。
netsh http add sslcert ipport=0.0.0.0:443 appid={12345678-db90-4b66-8b01-88f7af2e36bf}
certhash="83ae3ca2c538b95e5037e033a873002e1890f5ba"
appid
和 certhash
值可以通过运行以下命令找到
netsh http show sslcert
这里,所有0表示此机器上的所有IP地址。它也可以是一个特定的IP地址。
注意:通过netsh进行此类更改后,请不要忘记重新启动您的服务器/计算机(因为这些更改适用于内核模式进程)。
这里有一个很好的实用工具可以提供UI来查看和管理http.sys
绑定。该文章还解释了url acls,这在自托管应用程序/Web服务的情况下更为相关。
使用客户端证书进行客户端身份验证
SSL可以配置为允许服务器使用客户端证书对客户端进行身份验证。但是,在这种情况下,服务器和客户端需要一些额外的配置步骤。
在此模式下,服务器(在SSL握手期间)可以配置为以提示的形式将可接受(受信任)的证书颁发者列表发送给客户端浏览器(如果它是浏览器)。然后,浏览器会在用户的个人证书存储中(具有私钥访问权限)检查可用的客户端证书,这些证书的颁发者链中包含服务器发送的提示中的任何CA。如果找到任何此类证书,系统会向用户显示一个屏幕,用户可以在其中选择要发送到服务器的证书。
或者,如果服务器没有发送这样的提示,浏览器会显示用户在“个人”证书存储中拥有的所有客户端证书(带私钥)。一旦用户选择了一个证书进行客户端验证,浏览器就会在https请求中发送该证书的公钥。在服务器上成功验证客户端证书后,请求被授予或拒绝访问。
在Windows操作系统中,客户端证书验证的实际实现存在一些灰色区域。客户端证书由http.sys
在传输层进行“协商”。Http.sys
可以(通过netsh命令)选择性地配置为始终在SSL握手期间进行此协商。或者,如果此协商尚未发生,IIS(/应用程序主机)可以随时请求http.sys
进行此协商(例如,如果子目录的访问受到基于客户端证书的身份验证的限制)。在这种情况下,SSL会话将重新协商;这次,带有客户端证书要求。Http.sys
然后根据CRL和CTL(或证书存储)进行客户端证书验证(一旦客户端/浏览器将其传递给它),并且还可以配置为将客户端证书映射到AD用户。然后,HTTP请求连同客户端证书一起传递给IIS(和应用程序)。
提示:如果您想查看SSL握手期间从服务器发送的内容,请下载并安装OpenSSL,然后从此处下载适用于Windows的OpenSSL工具。例如,如果您想测试需要客户端证书身份验证的https://dummyblah.com,请在“OpenSSL”命令提示符下使用以下命令(一次一个)
s_client -connect dummyblah.com:443 -prexit
GET /
在我们开始之前,让我们讨论几个重要概念
证书吊销列表(CRL)
CRL是CA已撤销(取消)的证书序列号列表。CA(已颁发证书)有责任提供一个设施,让客户端知道某个特定证书是否已被撤销。而且,客户端有责任向CA核实其颁发的证书是否已被撤销。最后这句话很重要,因为即使CA已撤销证书,如果客户端(例如浏览器)没有检查吊销列表,该证书在客户端看来仍然有效。不同的浏览器在CRL检查方面有不同的行为。一些重要问题已在此处指出。
CA维护并在客户端可以访问的位置托管此类CRL文件。此位置的URL可以在证书的“CRL分发点”扩展属性下找到。
CRL文件可以是基础文件和一些增量文件(对基础文件的较小中间添加)。客户端可以下载这些文件并缓存一段时间。然而,这种下载文件(无论大小)的机制可能意味着SSL握手会有一点延迟。此外,通过URL公开发布的CRL文件容易受到拒绝服务攻击(DOS / DDOS)。为了避免这些问题,有一种替代(较新)的检查证书是否被吊销的方法,称为“在线证书状态协议(OCSP)”。OCSP允许检查单个证书是否被吊销。客户端可以使用OCSP或回退到基于CRL文件的检查。
当IIS收到HTTP请求中的客户端证书(并且配置为接受和验证它)时,它也会进行CRL检查。请记住,这是必不可少的步骤,如果主机(IIS)和CRL链接之间的连接中断,客户端证书验证将失败并显示错误代码403.13。但是,对于自签名证书,CRL检查没有意义,因此证书的“权限信息访问”和“CRL分发点”字段在证书中将不需要,并且不会进行CRL检查。
证书信任列表(CTL)
证书信任列表是受信任CA的列表。服务器可以配置为信任许多全球根CA和许多内部/外部CA。IIS可以配置为根据这些受信任的证书颁发机构对客户端证书进行身份验证。但是,这意味着任何由这些知名根(/中间)CA颁发的客户端证书都将被视为有效。为了避免这种情况,可以创建和配置一个“CTL”(在系统级别或网站级别),它充当验证的“过滤器”。如果这样做,客户端证书必须由配置的CTL中的某个CA颁发。请记住,CRL检查仍然会进行。
在SSL握手期间,CTL传统上(IIS6之前)也曾被发送到浏览器,以建议(提示)浏览器服务器正在寻找哪个客户端证书。然后,浏览器会显示如下消息,供用户选择合适的证书。然而,自IIS6以来,微软改变了这种行为。IIS不再将CTL作为提示发送给浏览器,而是发送所有受信任的根CA列表(令人困惑的是,此列表在某些技术文档中也被称为CTL)。
这种在客户端证书验证期间向客户端发送提示的行为可以通过更改位于以下位置的Windows注册表中“SendTrustedIssuerList
”(DWord
)键的值来控制
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/SecurityProviders/SCHANNEL
默认情况下,在Windows 8/Windows Server 2012之前,此值为1
(true)。如果关闭此行为(通过将此键设置为0
),浏览器将不会收到任何提示,因此会向用户显示用户个人证书存储中的所有客户端证书(甚至包括服务器不信任的证书)。
注意:如果服务器上“受信任的根CA”存储数量过大,可能会出现一些并发症。如果是这样,浏览器提示可能会中断或溢出,浏览器会向用户显示一个空白消息窗口(没有建议的证书)或一个截断列表(让您彻底困惑)。因此,为安全起见,除非您非常确定将受信任的根CA存储保持在一定大小限制内,否则不建议将CTL发送给客户端。此处有一些详细信息:http://netsekure.org/2011/04/tls-client-authentication-and-trusted-issuers-list/
如果您想创建用于客户端证书身份验证的CTL(即使不提示客户端),可以使用名为MakeCTL.exe的工具创建,如此帖子中指出。令人惊讶的是,自Windows 2003 Server以来,微软没有提供基于良好UI的工具来创建CTL文件,我猜是因为.NET框架(和WIF)提供了更流行、更简单的替代方案,可以在服务器上的代码中验证客户端证书(我将在本文后面解释)。
随着 Windows Server 2012 和 Windows 8 的发布,微软改变了客户端证书验证模型。不再支持基于 CTL 的验证。相反,证书存储用于此目的。现在有一个新的专用存储,名为“客户端身份验证颁发者 (ClientAuthIssuer
)”,它充当在机器级别列出用于基于客户端证书的身份验证的 CA 的占位符。此外,可以定义自定义凭据存储并用于验证单个网站。因此,首先检查网站的自定义凭据存储(如果已配置),如果不存在,则检查 ClientAuthIssuer
存储(如果已配置)。最后,默认情况下会检查“受信任的根证书颁发机构”存储。此外,如前所述,默认情况下不会向浏览器发送提示,并且“SendTrustedIssuerList
”注册表项的默认值为 0
。
正如本文所述,您可以使用以下命令将ClientAuthIssuer
证书存储绑定到SSL端口以进行客户端证书验证
netsh http add sslcert ipport=0.0.0.0:443 certhash=GUID hash value appid={GUID application identifier} sslctlstorename=ClientAuthIssuer
注释
- 由于这会影响内核模式进程(在
http.sys
中),您需要重新启动计算机才能应用更改。 - 即使
ClientAuthIssuer
存储配置为客户端证书验证,CA也必须位于“受信任的根证书颁发机构”存储中。
顺便提一下,请注意存在一个名为“Web Hosting”的存储,它作为“个人”存储的补充,并具有容纳更多证书的可伸缩性。
配置IIS进行客户端证书验证
IIS需要配置为“接受”或“要求”客户端证书,如下图所示
- 如果选择“接受”,并且提供了客户端证书,IIS将接受该证书,验证它,并将HTTP请求连同证书转发到应用程序。
如果未提供客户端证书,IIS仍将该HTTP请求(不带证书)转发到应用程序。 - 如果选择“要求”,并且提供了客户端证书,IIS将接受该证书,验证它,并将HTTP请求连同证书转发到应用程序(就像“接受”选项一样)。但是,如果未提供客户端证书,IIS将向客户端抛出Http错误403.7 – 禁止访问。
您可以通过使用以下内容在配置文件(web.config)中设置这些值
<system.webServer>
<security>
<access sslFlags="ssl">
</security>
</system.webServer>
这里,“ssl
”等同于IIS中的“Require SSL”选项,“sslNegotiateCert
”等同于客户端证书 -> “Accept
”,“sslRequireCert
”等同于客户端证书 -> “Require”。
除了仅通过客户端证书验证客户端请求之外,IIS还可以用于配置身份验证并将客户端证书映射到Windows用户。如果这样配置,IIS会将请求模拟为Windows用户帐户。IIS 7+中有两个原生模块,名为“CertificateMappingAuthenticationModule
”和“IISCertificateMappingAuthenticationModule
”,可让您执行此操作。前者需要Active Directory (AD) 域的存在,而后者则提供了在没有AD的情况下工作的灵活性。配置可以通过web.config使用<clientCertificateMappingAuthentication>
标签或<iisClientCertificateMappingAuthentication>
标签进行。此外,IISClientCertificateMapping
提供了执行一对一映射或多对一映射的功能。我不会详细介绍如何执行此操作(因为本文会太长),但是,以下文章将为您提供良好的理解
您是否已经看到使用IIS进行基于客户端证书的身份验证的价值?是的,通过互联网对用户进行身份验证和管理的全部麻烦可以从您的Web应用程序(基于.NET或非.NET)中移除,并分配给IIS和AD(以及您组织中的基础设施团队,太棒了!!!)。当然,这并非总是用例,但在身份验证针对组织用户或用户群有限的情况下,这可能是一种福音(在狭义范围内,是VPN的替代方案)。
使用IIS进行客户端证书身份验证最大的问题(或者说是缺乏便利)在于您无法对异常处理、日志记录(除了IIS日志)和警报进行更精细的控制。这是大多数开发人员更喜欢在服务器端代码(应用程序内)中验证客户端证书的最常见原因之一。
在代码中验证客户端证书
客户端认证验证(和身份验证)可能比我们目前看到的要复杂得多;例如,我们可能需要从传入的客户端证书中提取更多信息,并将其用于进一步的身份验证(或授权)。在现代基于网络的IT技术中,联合安全和基于声明的身份扮演着重要角色。客户端可能是一个应用程序(而不是用户),在经过身份验证服务器的认证后与某个资源服务器进行通信。客户端证书在客户端和服务器之间或服务器和服务器之间建立“信任”方面发挥着重要作用,并且在代码中操作客户端证书变得必要。
我在此文章中附带了三个项目,其中包含一些关于如何在代码中验证和处理客户端证书的示例。这些可能不一定是最好的示例,但是它们将帮助您入门。
在WCF服务中验证客户端证书
IIS 架构
在IIS 7+中,与以前版本IIS相比,最重要的变化是包含了WAS以及独立托管和处理基于HTTP、MSMQ、TCP和NamedPipe的服务的能力(请看图像中可能的垂直切片)。因此,您可以托管一个net.tcp WCF服务,而不依赖于HTTP.SYS和W3SVC,甚至可以关闭或卸载这些驱动程序和服务,而不会影响WCF服务。
有几点需要注意
- HTTP.SYS是一个内核模式进程。它(正如预期)拥有安全机制,控制哪些进程可以注册端口并要求它传递HTTP流量。此访问由名为“URL访问控制列表(ACL)”的机制控制。用户必须列在端口(/ URL)的对应位置,才能“保留”注册进程(应用程序)以访问该端口上的流量的权限。默认情况下,只有管理员用户拥有完全权限。使用“
netsh http add urlacl…
”命令(带适当参数)将非管理员用户添加到URL ACL。这在自托管应用程序和WCF服务的情况下尤其如此。请Google“URL保留和注册”以获取更多详细信息。 - 在任何给定时间,只有一个进程可以“绑定”到一个端口。例如,默认情况下,
http.sys
占用端口80和443。然后,当您从IIS管理控制台创建绑定时,它可以绑定到额外的端口(如果可用)。但是,无论出于何种原因,如果您无法访问所需的端口,并且想知道哪个进程正在使用它,您可以运行以下命令(在管理员模式下),然后将PID与Windows任务管理器中当前运行的进程进行映射
netstat -o -n -a
即使http.sys
也可以关闭(例如,如果您想安装Apache并关闭IIS),方法是转到“控制面板”->“设备管理器”->(“查看”->“显示隐藏设备”)->“非即插即用驱动程序”->“HTTP”,然后在“驱动程序”选项卡中将启动类型从“按需”更改为“禁用”。 - .NET的
HttpListener
类直接位于http.sys
之上。因此,它自动实现了其中所有丰富的功能。这比在网络编程中使用TcpListener
类或套接字具有许多优势。但是,如果出于任何原因您想使用TCP,WCF是更优选的选项(优于TCPListener
/Sockets
),因为它具有丰富的开箱即用功能(在net.tcp
中)。此外,net.tcp
可以配置为进行端口共享(使用“net.tcp
端口共享服务”),类似于http.sys
共享端口80和443。
WCF客户端证书配置
WCF功能强大、用途广泛且内容庞大。我将只粗略地介绍其安全功能,并且仅限于与证书相关的部分。
WCF服务可以配置为使用“传输”安全、“消息”安全或两者结合的“TransportWithMessageCredential
”安全。简而言之,传输安全在传输层实现,消息安全在应用层实现。两者各有利弊,最大的缺点是传输安全必须在每个跳点配置且依赖协议,而消息安全由于无法使用硬件加速而速度稍慢。基于消息安全的最大优点是它可以配置自定义身份验证(例如,用户名/密码或某些安全令牌),因为它位于应用层。“TransportWithMessageCredential
”提供了两者的最佳结合。
以下是使用传输安全时服务器端和客户端的配置示例。在这种情况下,我使用的是WSHttpBinding
,但也可以使用BasicHttpBinding
。我省略了mex绑定,因为我不需要在Visual Studio中自动生成代理。
服务器端(正在被调用的WCF服务)
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBindingConfiguration" >
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>
</binding>
</basicHttpBinding>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="BlahServiceBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="PeerTrust"
trustedStoreLocation="LocalMachine" revocationMode="NoCheck" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="BlahDataService" behaviorConfiguration="BlahDataServiceBehavior">
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="basicHttpBindingConfiguration" contract="IBlahDataService" />
<endpoint contract="IMetadataExchange" binding="wsHttpBinding"
address="mex" bindingConfiguration="wsHttpEndpointBinding" />
</service>
</services>
</system.serviceModel>
这里,
PeerTrust
(强制客户端证书的公钥存在于服务端的“受信任人员”证书存储中)ChainTrust
(证书必须根据完整的证书链进行验证)
客户端(调用服务)
<system.serviceModel>
<client>
<endpoint address="https://www.blah.com/BlahService.svc"
behaviorConfiguration="ClientCertificateBehavior"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IBlahService"
contract="BlahServiceReference.IBlahService" name="BasicHttpBinding_IBlahService" />
</client>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IBlahService" >
<security mode="Transport" />
</binding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="ClientCertificateBehavior">
<clientCredentials>
<clientCertificate findValue="BlahCertificate"
storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
这篇文章提供了如何使用消息安全实现客户端证书身份验证的详细信息。
正如我之前提到的,WCF允许安全和绑定类型的强大组合。以下配置片段展示了netTcp
绑定与TransportWithMessageCredential
,在传输层使用Windows身份验证,在消息(应用程序)层使用证书身份验证。
<bindings>
<netTcpBinding>
<binding name="customBinding">
<security mode="TransportWithMessageCredential" >
<transport clientCredentialType="Windows" />
<message clientCredentialType="Certificate" />
</security>
</binding>
</netTcpBinding>
</bindings>
结论
希望您喜欢这篇文章。再次强调,请给出您宝贵的建议和更正。更多关于安全的文章即将推出...
历史
- 2016年4月22日:初始版本