2

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>

私の Web サービスでは、次のバインディングを使用してみました。

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

(私が customBinding を使用している理由は、SOAP 1.1 で WS-Addressing と WS-Security の両方をサポートする必要があり、この回答からアドバイス受けたためです。)

Fiddler を介してサンプル要求を実行すると、WCF トレースに次のエラーが表示されます。

' System.IdentityModel.Tokens.UserNameSecurityToken ' トークン タイプのトークン認証子が見つかりません。そのタイプのトークンは、現在のセキュリティ設定に従って受け入れることができません。

これは、を認証できないためだと思います<UsernameToken>。バインディング セキュリティを次のように変更した場合:

<security authenticationMode="UserNameForCertificate">

次に、次のエラーが表示されます。

' System.IdentityModel.Tokens.X509SecurityToken ' トークン タイプのトークン認証子が見つかりません。そのタイプのトークンは、現在のセキュリティ設定に従って受け入れることができません。

<BinarySecurityToken>これは、 !を認証できないためだと思います。

したがって、問題は次のとおりです。

  1. エラー メッセージの原因 (現在の構成では 1 つのトークンしか処理できないということ) についての私の仮定は正しいですか?
  2. 両方のトークンを受け入れるように構成するにはどうすればよいですか?

アップデート

@Yaron のおかげで、カスタム バインディング拡張機能が追加され、UserNameSecurityTokenX509SecurityTokenの両方が検証されています。

ただし、XML 署名を検証する段階で失敗しています。HTTP 応答で返される例外は次のとおりです。

メッセージのセキュリティ検証に失敗しました。

サービス トレース ビューアーでスタック トレースを詳しく調べると、次のように表示されます。

System.Security.Cryptography.CryptographicException...

署名の検証に失敗しました。

System.IdentityModel.SignedXml.VerifySignature (HashAlgorithm ハッシュ、AsymmetricSignatureDeformatter デフォーマッター) で System.IdentityModel.SignedXml.StartSignatureVerification (SecurityKey validationKey) で...

なぜこれが起こっているのかを理解するのを手伝ってくれる人はいますか? 私は今のところ迷っています。サンプル コードを使用して署名を手動で検証しようとしましたが、署名が無効であると表示されます。サプライヤーに戻る前に、どうすればそうであるかどうかを確認できますか? これはうまくいくはずですか?どこかで証明書を共有する必要がありますか?

4

1 に答える 1

4

コードからバインディングを作成する必要があります。

        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());

(あなたの投稿では、使用している SOAP バージョンや ssl が適用されているかどうかがわからないため、一部の値は推定値です)

後で実行する可能性のある別の落とし穴は、ServiceContract 属性に ProtectionLevel.SignOnly が必要であるということですが、これはこの質問には関係ありません。

于 2012-06-12T17:19:39.170 に答える