【问题标题】:WCF SOAP call with both username token and client certificate带有用户名令牌和客户端证书的 WCF SOAP 调用
【发布时间】:2014-08-28 20:15:15
【问题描述】:

我正在尝试使用用户名令牌(用户名/密码)和客户端证书来调用 Web 服务(不确定后端是用什么编写的)。

短版:如果我有客户端证书和用户名/密码可以使用,需要哪种 WCF 代码/配置组合来生成下面的 SOAP 标头?

加长版

以下是 Visual Studio 2010 中“添加服务引用”生成的服务接口(更改名称/URI 以保护无辜者):

 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(Namespace="http://servicenamespacehere", ConfigurationName="Service.Contract.ConfigName.Here")]
    public interface IBackendService {

        // CODEGEN: ...
        [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://servicenamespacehere#Method1")]
        [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
        void Method1(Method1Params request);

我需要生成的调用的 SOAP 安全标头如下所示:

<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 s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
         <u:Timestamp u:Id="_0">
            <u:Created>2014-08-26T20:22:50.522Z</u:Created>
            <u:Expires>2014-08-26T20:27:50.522Z</u:Expires>
         </u:Timestamp>
         <o:UsernameToken u:Id="uuid-6f243c9c-fd85-4634-8b57-cb196aee3195-60591">
            <o:Username>myUser</o:Username>
            <o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">somePwd</o:Password>
         </o:UsernameToken>
         <o:BinarySecurityToken u:Id="uuid-6f243c9c-fd85-4634-8b57-cb196aee3195-60592" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">BASE64TOKENHERE=</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>BASE64DIGESTHERE=</DigestValue>
               </Reference>
            </SignedInfo>
            <SignatureValue>BASE64SIGNATUREHERE=</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-6f243c9c-fd85-4634-8b57-cb196aee3195-60592"/>
               </o:SecurityTokenReference>
            </KeyInfo>
         </Signature>
      </o:Security>
   </s:Header>
   SOAP XML PAYLOAD FOLLOWS...

我找不到任何支持客户端消息凭据的 WCF 绑定/端点设置组合,其中包括 UserNameCertificate 类型。

作为一些搜索的结果,我发现有人表示我需要自定义 WCF 绑定来包含这两种凭据类型,他们指向此 MSDN 链接:

http://msdn.microsoft.com/en-us/library/ms751480(v=vs.100).aspx

但是当我按照代码示例时,我得到一个错误:

'The service certificate is not provided for target' 

现在 ClientCredentials 对象同时具有 ClientCertificate 属性(我通过客户端证书的指纹成功加载了该属性),但 ServiceCertificate 的用途是什么?

如果我只有一个客户端证书和一个用户名/密码可以使用,那么生成上面的 SOAP 标头需要什么 WCF 代码/配置组合?

【问题讨论】:

    标签: c# .net wcf soap ws-security


    【解决方案1】:

    这只能通过代码绑定来完成:

            var b = new CustomBinding();
            var sec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
            sec.EndpointSupportingTokenParameters.Signed.Add(new UserNameSecurityTokenParameters());
            sec.MessageSecurityVersion =
                MessageSecurityVersion.
                    WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
            sec.IncludeTimestamp = false;
            sec.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.EncryptBeforeSign;
    
            b.Elements.Add(sec);
            b.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
            b.Elements.Add(new HttpsTransportBindingElement());
    

    【讨论】:

    • 您的回答帮助我解决了 vmware wse 到 wcf 的迁移问题,我希望我可以直接给您一些我的代表!谢谢!
    【解决方案2】:

    我不确定我是否理解正确,但通过查看您的错误,您似乎在创建端点以验证服务时没有通过证书。

       // Create the service host
       ServiceHost myServiceHost = 
        new ServiceHost(typeof(Calculator), httpUri);
    myServiceHost.AddServiceEndpoint(typeof(ICalculator), binding, "");
    
    // Specify a certificate to authenticate the service.
    myServiceHost.Credentials.ServiceCertificate.
        SetCertificate(StoreLocation.LocalMachine,
        StoreName.My,
        X509FindType.FindBySubjectName,
        "Contoso.com");
    

    http://msdn.microsoft.com/en-us/library/ms733098.aspx

    【讨论】:

    • 我刚刚在你发帖前几分钟解决了这个问题。您的答案是解决方案的一部分,但不是全部。如果实际上没有服务证书(只有一个客户端证书的“相互证书”),还有其他需要跳过的环节。我正在等待拥有 Web 服务的供应商来验证我的调用是否正常。如果是这样,我会回来考虑将其标记为答案。
    猜你喜欢
    • 2011-08-31
    • 2012-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-14
    • 1970-01-01
    • 1970-01-01
    • 2015-05-03
    相关资源
    最近更新 更多