使用证书签署WCF消息

时间:2015-04-15 12:41:00

标签: wcf certificate sign

我正在尝试拨打第三方服务。我需要用证书签署我的消息。

我使用SOAPUI检查了连接,它运行正常。我现在正试图从WCF客户端进行调用,但无法使其工作。 我对此并不熟悉,可能错过了一个明显的步骤。

svcutil生成的配置如下所示:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="ServiceBinding">
          <security mode="Transport" />
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://url.com" binding="basicHttpBinding"
          bindingConfiguration="ServiceBinding" contract="ServiceContract"
          name="Name" />
    </client>
  </system.serviceModel>
</configuration>

我添加了一个endpointBehaviour来从商店获取证书。我还必须更改绑定配置,因为签名没有添加到消息中;我将安全模式更改为TransportWithMessageCredentials,并将邮件的客户端凭据类型设置为Certificate。 修改后的配置如下所示(我删除了不相关的部分):

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="ServiceBinding">
          <security mode="TransportWithMessageCredential">
            <message clientCredentialType="Certificate"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://url.com" behaviorConfiguration="Behavior"
        binding="basicHttpBinding" bindingConfiguration="ServiceBinding"
        contract="ServiceContract" name="Name" />
    </client>
    <behaviors>
      <endpointBehaviors>
        <behavior name="Behavior">
          <clientCredentials>
            <clientCertificate storeName="My" x509FindType="FindByThumbprint" findValue="..."/>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
</configuration>

当我尝试拨打电话时,我收到以下错误:

  

安全处理器无法在中找到安全标头   信息。这可能是因为消息是不安全的故障或   因为通信方之间存在绑定不匹配。   如果为安全性和服务配置了服务,则会发生这种情况   客户端没有使用安全性。

我发现了一些有关此错误的帖子,但没有一个可以帮助我。 我添加了ProtectionLevel=System.Net.Security.ProtectionLevel.Signthis post中所示的ServiceContractAttribute。

提前感谢您提供的任何帮助。

编辑:

在检查跟踪日志时,我看到消息已发送,并且我收到了有意义的响应。但是,响应中没有标题(我假设它会导致异常)。有没有办法可以将我的客户端配置为检查响应中的标头?

追踪请求:

<?xml version="1.0"?>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
  <System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
    <EventID>0</EventID>
    <Type>3</Type>
    <SubType Name="Information">0</SubType>
    <Level>8</Level>
    <TimeCreated SystemTime="2015-04-21T09:41:19.9227910Z"/>
    <Source Name="System.ServiceModel.MessageLogging"/>
    <Correlation ActivityID="{ba5c25df-1f0a-4375-8b15-e2160e21bc14}"/>
    <Execution ProcessName="w3wp" ProcessID="8540" ThreadID="16"/>
    <Channel/>
    <Computer>PC673</Computer>
  </System>
  <ApplicationData>
    <TraceData>
      <DataItem>
        <MessageLogTraceRecord xmlns="http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace" Time="2015-04-21T11:41:19.9217909+02:00" Source="TransportSend" Type="System.ServiceModel.Security.SecurityAppliedMessage">
          <Addressing>
            <Action/>
            <To>https://url.com</To>
          </Addressing>
          <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <s:Header>
              <o:Security xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" s:mustUnderstand="1">
                <u:Timestamp u:Id="_0">
                  <u:Created>2015-04-21T09:41:08.287Z</u:Created>
                  <u:Expires>2015-04-21T09:46:08.287Z</u:Expires>
                </u:Timestamp>
                <o:BinarySecurityToken>
                  <!-- Removed-->
                </o:BinarySecurityToken>
                <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
                  <SignedInfo>
                    <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                    <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                    <Reference URI="#_0">
                      <Transforms>
                        <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                      </Transforms>
                      <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                      <DigestValue>zvttNRawVVcleH5WAYMCi7oBzpM=</DigestValue>
                    </Reference>
                  </SignedInfo>
                  <SignatureValue>iEMTR/xKruW1TeqJiPdXjNKG3D4ZWyfFM3T+iPy8NSCpwQIpwXmsmrOjT2N5QJoG7S+wyIm2Vsa4rmlmyYBM18rNMeN+luHuUYvNh9ammWyYgam5/mpGBmR8KJiyPSiCxCPeUWuL8z5ag2wGtTrTH/JqOsHfdobnhznvQJgPAc8YWAk6On7SkHT+nKikGv1rEfbCtOBeggbBLLzSArVOBDDOZhWRpRJLhvU6XhlYj1IbgMy4tFP8f0+SESU/UQM+0bBnt0IDwwtTQIyeheifVJINeUHe+T1Pr8qYtyo9/sLulr1vkFe0DAokv1R1WRCU5IoE38I/ptILOMvIq1s3OQ==</SignatureValue>
                  <KeyInfo>
                    <o:SecurityTokenReference>
                      <o:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#uuid-bda377d4-237a-46b7-a7c3-b7d47578c278-1"/>
                    </o:SecurityTokenReference>
                  </KeyInfo>
                </Signature>
              </o:Security>
            </s:Header>
            <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
              <!-- Valid request -->
            </s:Body>
          </s:Envelope>
        </MessageLogTraceRecord>
      </DataItem>
    </TraceData>
  </ApplicationData>
</E2ETraceEvent>

回应痕迹:

<?xml version="1.0"?>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
  <System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
    <EventID>0</EventID>
    <Type>3</Type>
    <SubType Name="Information">0</SubType>
    <Level>8</Level>
    <TimeCreated SystemTime="2015-04-21T09:41:22.4049329Z"/>
    <Source Name="System.ServiceModel.MessageLogging"/>
    <Correlation ActivityID="{ba5c25df-1f0a-4375-8b15-e2160e21bc14}"/>
    <Execution ProcessName="w3wp" ProcessID="8540" ThreadID="16"/>
    <Channel/>
    <Computer>PC673</Computer>
  </System>
  <ApplicationData>
    <TraceData>
      <DataItem>
        <MessageLogTraceRecord xmlns="http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace" Time="2015-04-21T11:41:22.4049329+02:00" Source="TransportReceive" Type="System.ServiceModel.Channels.BufferedMessage">
          <HttpResponse>
            <StatusCode>OK</StatusCode>
            <StatusDescription>OK</StatusDescription>
            <WebHeaders>
              <X-Backside-Transport>OK OK</X-Backside-Transport>
              <Connection>Keep-Alive</Connection>
              <Transfer-Encoding>chunked</Transfer-Encoding>
              <X-Client-IP>194.78.45.187</X-Client-IP>
              <Content-Type>text/xml</Content-Type>
              <Date>Tue, 21 Apr 2015 09:41:11 GMT</Date>
              <Server>Apache-Coyote/1.1</Server>
            </WebHeaders>
          </HttpResponse>
          <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
            <s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"/>
            <Body>
              <!-- Meaningful response - the same I get when using SOAPUI -->
            </Body>
          </Envelope>
        </MessageLogTraceRecord>
      </DataItem>
    </TraceData>
  </ApplicationData>
</E2ETraceEvent>

2 个答案:

答案 0 :(得分:2)

我通过创建自定义绑定来修复此问题。

<binding name="ServiceBinding">
  <security authenticationMode="CertificateOverTransport"
    messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
    requireDerivedKeys="false"
    securityHeaderLayout="Lax"
    enableUnsecuredResponse="true" />
  <textMessageEncoding messageVersion="Soap11" />
  <httpsTransport />
</binding>

这里的关键是enableUnsecuredResponse="true"。这样,我可以收到未签名的响应而不会崩溃。

答案 1 :(得分:1)

wcf中的绑定在客户端和服务器端必须相同。如果将securitymode设置为transport,则不会对其自身的消息进行加密。它只是一个安全的隧道。 因此,将securitymode设置为message,将protectionlevel设置为加密和签名。

以下是加密选项的概述: https://msdn.microsoft.com/en-us/library/ff650862.aspx