使用证书的WCF消息安全性 -

时间:2011-02-13 12:58:27

标签: .net wcf x509certificate

我正在尝试创建一个将使用证书的消息模式安全性的WCF服务。当我在IIS和cassini中运行服务代码时,我收到以下消息

  

很可能是证书   'CN = TempCA'可能没有私钥   能够进行密钥交换的   进程可能没有访问权限   私钥

我使用以下命令创建了证书

makecert -n "CN=TempCA" -r -sv TempCA.pvk TempCA.cer -sky Exchange -pe
makecert -sk SignedByCA -iv TempCA.pvk -n "CN=SignedByCA" -ic TempCA.cer SignedByCA.cer -sr localmachine -ss My

TempCA.cer已导入“受信任的根证书颁发机构\证书”,SignedByCA.cer已导入“个人\证书”

然后我运行了以下命令

pvk2pfx.exe -pvk TempCA.pvk -spc TempCA.cer

并将TempCA.pfx导入“个人\证书”

服务配置文件如下(取自MSDN教程并针对我的项目进行了修改)

<system.serviceModel>
    <services>
      <service name="Service.Service1" behaviorConfiguration="wsHttpEnpointBinding">
        <endpoint address="http://localhost:5372/Service1.svc" binding="wsHttpBinding"
         bindingConfiguration="wsHttpEndpointBinding" name="wsHttpEndpoint"
         contract="Service.Contracts.IService1" />
      </service>      
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="wsHttpEnpointBinding">
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceMetadata httpGetEnabled="true" />
          <serviceCredentials>
            <!-- Certificate storage path on the server -->
            <serviceCertificate findValue="TempCA" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" />
            <issuedTokenAuthentication allowUntrustedRsaIssuers="true" />
            <!-- Certificate storage path in the client -->
            <clientCertificate>
              <certificate findValue="TempCA" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
            </clientCertificate>            
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="wsHttpEnpointBinding">
          <clientCredentials>
            <clientCertificate findValue="TempCA" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
            <serviceCertificate>
              <authentication certificateValidationMode="None" />
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttpEndpointBinding">
          <security mode="Message">
            <message clientCredentialType="Certificate"  />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
  </system.serviceModel>

我花了相当多的时间来解决这个问题,但我没有取得任何实际进展......

1 个答案:

答案 0 :(得分:1)

问题似乎是调用应用程序用户帐户没有读取证书的权限。

使用以下命令将权限授予网络服务帐户

WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s Temp.cer -a "Network Services"

...并使用以下绑定修复了问题

<system.serviceModel>
    <services>
      <service name="Service.Service1" behaviorConfiguration="wsHttpEnpointBinding">
        <endpoint address="http://localhost:5372/Service1.svc" binding="wsHttpBinding"
         bindingConfiguration="wsHttpEndpointBinding" name="wsHttpEndpoint"
         contract="Service.Contracts.IService1" />
      </service>      
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="wsHttpEnpointBinding">
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceMetadata httpGetEnabled="true" />
          <serviceCredentials>
            <!-- Certificate storage path on the server -->
            <serviceCertificate findValue="TempCA" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" />
            <issuedTokenAuthentication allowUntrustedRsaIssuers="true" />
            <!-- Certificate storage path in the client -->
            <clientCertificate>
              <certificate findValue="TempCA" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
            </clientCertificate>            
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="wsHttpEnpointBinding">
          <clientCredentials>
            <clientCertificate findValue="TemCA" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
            <serviceCertificate>
              <authentication certificateValidationMode="None" />
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttpEndpointBinding">
          <security mode="Message">
            <message clientCredentialType="Certificate"  />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
  </system.serviceModel>