【问题标题】:Accepting both UsernameToken and BinarySecurityToken in WCF customBinding在 WCF customBinding 中同时接受 UsernameToken 和 BinarySecurityToken
【发布时间】:2013-05-06 07:12:00
【问题描述】:

我正在使用 customBinding 端点构建 WCF Web 服务,并且在接受另一方发送给我的 WS-Security 标头时遇到问题。我们都遵循英国国家卫生服务局制定的规范,因此我无法修改要求。

<wsse:Security>标头的基本结构应该如下,根据规范:

<wsse:Security>
    <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurityutility-1.0.xsd" wsu:Id="6CCF6A2B-11A6-11DF-86D1-236A99759561" >
        <wsu:Created>2012-06-12T09:00:00Z</wsu:Created>
        <wsu:Expires>2012-06-12T09:15:00Z</wsu:Expires>
    </wsu:Timestamp>
    <wsse:UsernameToken>
        <wsse:Username>SomeUsername</wsse:Username>
    </wsse:UsernameToken>
    <wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wsssoap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-
200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="30b91ede-35c2-11df-aac9-97f155153931 ">xxx...</wsse: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="#6CCF6A2B-11A6-11DF-86D1-236A99759561" />
            <Transforms>
                <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>xxx...</DigestValue>
        </SignedInfo>
        <SignatureValue>xxx...</SignatureValue>
        <KeyInfo>
            <wsse:SecurityTokenReference>
                <wsse:Reference URI="#30b91ede-35c2-11df-aac9-97f155153931 "/>
            </wsse:SecurityTokenReference>
        </KeyInfo>
    </Signature>
</wsse:Security>

在我的网络服务中,我尝试使用以下绑定:

<customBinding>
    <binding name="wsHttpSoap11" >
        <textMessageEncoding messageVersion="Soap11WSAddressingAugust2004" />
        <security authenticationMode="MutualCertificate">
        </security>
        <httpTransport/>
    </binding>
</customBinding>

(我使用 customBinding 的原因是我必须同时支持 WS-AddressingWS-Security 而不是 SOAP 1.1,并且听取了this answer 的建议。)

如果我通过 Fiddler 运行示例请求,我的 WCF 跟踪中会出现以下错误:

找不到令牌验证器 'System.IdentityModel.Tokens.UserNameSecurityToken' 令牌类型。代币 根据当前的安全性,不能接受该类型的 设置。

我相信这是因为它无法验证&lt;UsernameToken&gt;。如果我将绑定安全更改为:

<security authenticationMode="UserNameForCertificate">

然后我得到这个错误:

找不到令牌验证器 'System.IdentityModel.Tokens.X509SecurityToken' 令牌类型。的代币 根据当前的安全设置,该类型不能被接受。

我相信这是因为它现在无法验证&lt;BinarySecurityToken&gt;

因此,问题是:

  1. 我对错误消息原因的假设是否正确 (它在当前配置中只能处理一个令牌)?
  2. 如何配置它以接受两个令牌?

更新

感谢@Yaron,我现在添加了一个自定义绑定扩展,并且 UserNameSecurityTokenX509SecurityToken 都在验证。

但是,它现在在验证 XML 签名的阶段失败了。 HTTP 响应中返回的异常是:

邮件安全验证失败。

如果我在服务跟踪查看器中深入挖掘堆栈跟踪,我会看到:

System.Security.Cryptography.CryptographicException...

签名验证失败。

在 System.IdentityModel.SignedXml.VerifySignature(HashAlgorithm 哈希, AsymmetricSignatureDeformatter deformatter) 在 System.IdentityModel.SignedXml.StartSignatureVerification(SecurityKey verificationKey)...

谁能帮我弄清楚为什么会这样?我现在有点迷路了。我尝试使用some sample code 尝试手动验证签名,但它说签名无效。在我回到供应商处之前,我如何确定它是否存在?这是应该工作的东西吗?我们应该在某个地方共享一些证书吗?

【问题讨论】:

    标签: wcf web-services 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 = true;
            sec.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.EncryptBeforeSign;
    
            b.Elements.Add(sec);
            b.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
            b.Elements.Add(new HttpTransportBindingElement());
    

    (有些值是估计的,因为我无法从您的帖子中看出您使用的是哪个肥皂版本或是否应用了 ssl)

    您可能会遇到的另一个问题是您需要在 ServiceContract 属性上设置 ProtectionLevel.SignOnly,但这与此问题无关。

    【讨论】:

    • 非常感谢您的回答 - 我明天回到办公室时会试试这个。我在我的问题中确实提到我正在使用 SOAP 1.1,这对您的示例代码有影响吗?
    • 没有影响,但如果我们也使用寻址,这可能会产生影响。如果您有任何问题,请发布完整的肥皂或发送给我
    • 请查看我的更新,如果有任何进一步的建议,将不胜感激。如果有用,很高兴向您发送完整的请求。
    • wcf 跟踪是否显示任何内部异常?它有时隐藏在主要的下面...如果没有更多信息,则使用完全相同的代码绑定构建一个 wcf 客户端来使用此服务。验证客户端是否正常工作,然后将其肥皂与实际收到的肥皂进行比较。哦等等 - 看着样品肥皂,它看起来只有肥皂主体签名?默认情况下,wcf 还需要对用户名令牌和时间戳进行签名。这一定有一些内在的例外。如果您将 includeTimestamp 设置为 false,您可能可以摆脱时间戳要求,但您需要 -
    • 带有时间戳的创意。首先找到那个内部异常,以便我们得到一些反馈。发现错误后,请告诉我们是否使用了 ssl。如果是这样,可能有办法使用 CreateMutualCertificateBindingElement 设置将其转换为传输绑定
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    • 2011-07-17
    • 2020-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多