WCF Message security using certificates -

浪尽此生 提交于 2019-12-08 01:22:37

问题


I am trying to create a WCF service that will use message mode security with a certificate. When I run the service code, both in IIS and cassini I get the following message

It is likely that certificate 'CN=TempCA' may not have a private key that is capable of key exchange or the process may not have access rights for the private key

I have created certificates using the following commands

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

The TempCA.cer has been imported into the "Trusted Root Certification Authorities\Certificates" and the SignedByCA.cer into the "Personal\Certificates"

I then ran the following command

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

and imported the TempCA.pfx into the "Personal\Certificates"

The service config file is as follows (Taken from an MSDN tutorial and modified for my project)

<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>

I have spent a considerable amount of time trying to resolve this but I'm not making any real progress...


回答1:


The problem seems to be the that the calling application user acount didn't have permission to read the certificate.

Using the following command to grant the permission to the Network services account

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

...and using the following bindings fixed the issue

<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>


来源:https://stackoverflow.com/questions/4984258/wcf-message-security-using-certificates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!