Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WCF证书身份验证不工作_C#_Wcf_Authentication_Certificate_Wcfserviceclient - Fatal编程技术网

C# WCF证书身份验证不工作

C# WCF证书身份验证不工作,c#,wcf,authentication,certificate,wcfserviceclient,C#,Wcf,Authentication,Certificate,Wcfserviceclient,我已经构建了一个WCF helloworld客户端和服务器。我想在它们之间使用证书身份验证 我得到的错误是“服务未对调用方进行身份验证。” 我使用makecert.exe创建了两个证书。客户端上的证书安装在“个人”、“受信任的人”和“第三方根证书颁发机构”下。我复制了证书,因为我不知道它是否应该只在一个标题下 我的服务器网络配置如下所示 <?xml version="1.0"?> <configuration>

我已经构建了一个WCF helloworld客户端和服务器。我想在它们之间使用证书身份验证

我得到的错误是“服务未对调用方进行身份验证。”

我使用makecert.exe创建了两个证书。客户端上的证书安装在“个人”、“受信任的人”和“第三方根证书颁发机构”下。我复制了证书,因为我不知道它是否应该只在一个标题下

我的服务器网络配置如下所示

            <?xml version="1.0"?>
            <configuration>
              <appSettings>
                <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
              </appSettings>
              <system.web>
                <compilation debug="false" targetFramework="4.5.1"/>
                <httpRuntime targetFramework="4.5.1"/>
              </system.web>
              <system.serviceModel>
                <services>
                  <service behaviorConfiguration="BusinessToBusiness" name="TestHelloWork.Service1">

                    <endpoint address="" binding="wsHttpBinding"  bindingConfiguration="BindingConfig" contract="TestHelloWork.IService1" /> 
                            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
                    <host>
                      <baseAddresses>
                        <add baseAddress="http://win-gat-web01:7777/Service1"/>
                      </baseAddresses>
                    </host>
                  </service>
                </services>
                <bindings>  
                  <wsHttpBinding>  
                    <binding name="BindingConfig">
                     <security>
                        <message clientCredentialType = "Certificate"/>
                     </security>
                    </binding>  
                  </wsHttpBinding>  
               </bindings>  
                <behaviors>
                  <endpointBehaviors>
                    <behavior name="webBehavior">
                      <webHttp/>
                    </behavior>
                  </endpointBehaviors>
                  <serviceBehaviors>
                    <behavior>
                      <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
                      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="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="true"/>
                    </behavior>
                    <behavior name="BusinessToBusiness">
                     <serviceCredentials>
                        <clientCertificate>
                           <authentication certificateValidationMode = "PeerTrust"/>
                        </clientCertificate>
                        <serviceCertificate findValue="WCfServer"
                storeLocation="LocalMachine"
                storeName="My"
                x509FindType="FindBySubjectName" />         
                     </serviceCredentials>
                     <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
                    </behavior>     
                  </serviceBehaviors>
                </behaviors>
                <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
              </system.serviceModel>
            </configuration>
            <?xml version="1.0"?>

            <!--
              For more information on how to configure your ASP.NET application, please visit
              http://go.microsoft.com/fwlink/?LinkId=169433
              -->

            <configuration>

                <system.web>
                  <compilation debug="true" targetFramework="4.5.1" />
                  <httpRuntime targetFramework="4.5.1" />
                </system.web>
              <system.serviceModel>
            <bindings>
              <wsHttpBinding>
                <binding name="WSHttpBinding_IService1">
                  <security>
                    <message clientCredentialType="Certificate" />

                  </security>
                </binding>
              </wsHttpBinding>
            </bindings>
            <client>
              <endpoint address="http://myserver:7777/Service.svc" binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
                name="WSHttpBinding_IService1" behaviorConfiguration="CustomBehavior">
                <identity>
                  <dns value="WCfServer" />
                </identity>
              </endpoint>
            </client>
            <behaviors>
              <endpointBehaviors>
                <behavior name="CustomBehavior">
                  <clientCredentials>
                    <clientCertificate findValue="WcfClient" x509FindType="FindBySubjectName"

                      storeLocation="CurrentUser" storeName="My" />
                    <serviceCertificate>
                      <authentication certificateValidationMode="PeerTrust"/>
                    </serviceCertificate>
                  </clientCredentials>
                </behavior>
              </endpointBehaviors>
            </behaviors>
            </system.serviceModel>
            </configuration>

客户端web.config如下所示

            <?xml version="1.0"?>
            <configuration>
              <appSettings>
                <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
              </appSettings>
              <system.web>
                <compilation debug="false" targetFramework="4.5.1"/>
                <httpRuntime targetFramework="4.5.1"/>
              </system.web>
              <system.serviceModel>
                <services>
                  <service behaviorConfiguration="BusinessToBusiness" name="TestHelloWork.Service1">

                    <endpoint address="" binding="wsHttpBinding"  bindingConfiguration="BindingConfig" contract="TestHelloWork.IService1" /> 
                            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
                    <host>
                      <baseAddresses>
                        <add baseAddress="http://win-gat-web01:7777/Service1"/>
                      </baseAddresses>
                    </host>
                  </service>
                </services>
                <bindings>  
                  <wsHttpBinding>  
                    <binding name="BindingConfig">
                     <security>
                        <message clientCredentialType = "Certificate"/>
                     </security>
                    </binding>  
                  </wsHttpBinding>  
               </bindings>  
                <behaviors>
                  <endpointBehaviors>
                    <behavior name="webBehavior">
                      <webHttp/>
                    </behavior>
                  </endpointBehaviors>
                  <serviceBehaviors>
                    <behavior>
                      <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
                      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="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="true"/>
                    </behavior>
                    <behavior name="BusinessToBusiness">
                     <serviceCredentials>
                        <clientCertificate>
                           <authentication certificateValidationMode = "PeerTrust"/>
                        </clientCertificate>
                        <serviceCertificate findValue="WCfServer"
                storeLocation="LocalMachine"
                storeName="My"
                x509FindType="FindBySubjectName" />         
                     </serviceCredentials>
                     <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
                    </behavior>     
                  </serviceBehaviors>
                </behaviors>
                <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
              </system.serviceModel>
            </configuration>
            <?xml version="1.0"?>

            <!--
              For more information on how to configure your ASP.NET application, please visit
              http://go.microsoft.com/fwlink/?LinkId=169433
              -->

            <configuration>

                <system.web>
                  <compilation debug="true" targetFramework="4.5.1" />
                  <httpRuntime targetFramework="4.5.1" />
                </system.web>
              <system.serviceModel>
            <bindings>
              <wsHttpBinding>
                <binding name="WSHttpBinding_IService1">
                  <security>
                    <message clientCredentialType="Certificate" />

                  </security>
                </binding>
              </wsHttpBinding>
            </bindings>
            <client>
              <endpoint address="http://myserver:7777/Service.svc" binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
                name="WSHttpBinding_IService1" behaviorConfiguration="CustomBehavior">
                <identity>
                  <dns value="WCfServer" />
                </identity>
              </endpoint>
            </client>
            <behaviors>
              <endpointBehaviors>
                <behavior name="CustomBehavior">
                  <clientCredentials>
                    <clientCertificate findValue="WcfClient" x509FindType="FindBySubjectName"

                      storeLocation="CurrentUser" storeName="My" />
                    <serviceCertificate>
                      <authentication certificateValidationMode="PeerTrust"/>
                    </serviceCertificate>
                  </clientCredentials>
                </behavior>
              </endpointBehaviors>
            </behaviors>
            </system.serviceModel>
            </configuration>

客户端证书安装在“个人”下


你知道会出什么问题吗?我在谷歌上搜索了一下,意识到他们应该在同一个域名上?但事实确实如此。当我的服务是外部服务时,域将如何工作?

尝试启用CAPI2日志。它是包含证书验证信息的特殊日志(默认情况下未启用)。如果您的问题在于证书验证过程失败,您将在那里找到有用的信息。寻找错误。在我的情况下,是这样的

  • 已处理证书链,但在信任提供程序不信任的根证书中终止
  • 无法将证书链构建到受信任的根颁发机构
  • 吊销功能无法检查吊销

就我而言,我已经

  • Client.pfx已导入客户端上的CurrentUser\My(个人)存储
  • 颁发client.pfx的CA证书(ClientCA)已导入到客户端上的LocalMachine存储和服务器上的LocalMachine存储的受信任根权限
  • 服务器上的LocalMachine\My(个人)存储中导入的server.pfx
  • 颁发server.pfx的CA证书(ServerCA)已导入客户端上的LocalMachine存储和服务器上的LocalMachine存储的受信任根权限
  • 从客户端和服务器都可以使用CRL到客户端CA
  • 从客户端和服务器都可以使用CRL到服务器CA
但是您使用的是
PeerTrust
证书验证模式,因此根据WCF演示中的评论,我有

将certificateValidationMode设置为PeerOrChainTrust意味着,如果证书位于用户的受信任人员存储中,则它将被信任,而无需对证书的颁发者链执行验证。此处使用此设置是为了方便起见,这样就可以运行示例,而不必拥有证书颁发机构(CA)颁发的证书

我假设证书的放置方式如下:

  • client.cer(仅来自client.pfx的证书)导入到服务器上LocalMachine存储中的受信任人员存储
  • server.cer(仅来自client.pfx的证书)导入到客户端上CurrentUser存储中的受信任人员存储中

验证您是否已将服务器私钥的权限授予运行IIS WCF服务的AppPool(默认池为
IIS AppPool\DefaultAppPool
) 可以使用
mmc
certlm.msc
在服务器证书上右键单击,然后
所有任务
->
管理私钥…
。验证您没有选定的广告,因为IIS APPPOOL是本地组。添加帐户
IIS应用池\您的应用池名称
,然后点击OK

如果应用程序池中有默认设置,例如
Identity
设置为
AplicationPoolIdentity
,而不是自定义帐户(通常使用AD中的托管服务帐户),并且
Load User Profile
设置为
true
,则该设置将起作用


您遇到的WCF证书身份验证问题很可能与使用MakeCert生成自签名证书时使用的选项有关

特别是,请确保您的证书支持必要的选项/用途。(例如,证书的“预期用途”字段应包括适当的值,如“服务器身份验证”或“客户端身份验证”。)

以下来自Microsoft的链接详细介绍了该过程。

注意:我们的团队在使用该工具进行