【问题标题】:validation of webservice answer throws "An incorrect X.509 Token Type is detected" exceptionWeb 服务答案的验证引发“检测到不正确的 X.509 令牌类型”异常
【发布时间】:2015-04-24 12:38:58
【问题描述】:

所以我正在实现一个带有 SSL 和签名内容的 SOAP 服务。服务所有者为 Web 服务安全 (WSS) 提供了一个 WSDL 和一个策略 XML。 Web 服务安全性由 CXF 2.7.15 处理。在 spring 上下文的端点和客户端配置中引用了策略文件。

我可以发送请求并接收答复。但是在尝试验证 WSS 标头时,会引发以下异常:

org.apache.cxf.ws.policy.PolicyException: These policy alternatives can not be satisfied: 
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}X509Token: An incorrect X.509 Token Type is detected
    at org.apache.cxf.ws.policy.AssertionInfoMap.checkEffectivePolicy(AssertionInfoMap.java:179)
    at org.apache.cxf.ws.policy.PolicyVerificationInInterceptor.handle(PolicyVerificationInInterceptor.java:101)
    at org.apache.cxf.ws.policy.AbstractPolicyInterceptor.handleMessage(AbstractPolicyInterceptor.java:44)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
    at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:849)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1626)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1515)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1317)
    at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:56)
    at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:223)
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:632)
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:572)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:481)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:382)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:335)
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:136)

策略文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<wsp:Policy
wsu:Id='Sig'
xmlns:wsu='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
  http://schemas.xmlsoap.org/ws/2005/07/securitypolicy
  http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/ws-securitypolicy.xsd
  http://schemas.xmlsoap.org/ws/2004/09/policy
  http://schemas.xmlsoap.org/ws/2004/09/policy/ws-policy.xsd  ">
<wsp:ExactlyOne>
    <wsp:All>
        <sp:AsymmetricBinding xmlns:sp='http://schemas.xmlsoap.org/ws/2005/07/securitypolicy'>
            <wsp:Policy>
                <sp:InitiatorToken>
                    <wsp:Policy>
                        <sp:X509Token sp:IncludeToken='http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient'>
                            <wsp:Policy>
                                <sp:WssX509V3Token10 />
                            </wsp:Policy>
                        </sp:X509Token>
                    </wsp:Policy>
                </sp:InitiatorToken>
                <sp:RecipientToken>
                    <wsp:Policy>
                        <sp:X509Token sp:IncludeToken='http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Always'>
                            <wsp:Policy>
                                <sp:WssX509V3Token10 />
                            </wsp:Policy>
                        </sp:X509Token>
                    </wsp:Policy>
                </sp:RecipientToken>
                <sp:AlgorithmSuite>
                    <wsp:Policy>
                        <sp:Basic256 />
                    </wsp:Policy>
                </sp:AlgorithmSuite>
                <sp:Layout>
                    <wsp:Policy>
                        <sp:Strict />
                    </wsp:Policy>
                </sp:Layout>
                <sp:OnlySignEntireHeadersAndBody />
            </wsp:Policy>
        </sp:AsymmetricBinding>
        <sp:Wss10 xmlns:sp='http://schemas.xmlsoap.org/ws/2005/07/securitypolicy'>
            <wsp:Policy>
                <sp:MustSupportRefEmbeddedToken />
            </wsp:Policy>
        </sp:Wss10>
        <sp:SignedParts xmlns:sp='http://schemas.xmlsoap.org/ws/2005/07/securitypolicy'>
            <sp:Body />
        </sp:SignedParts>
    </wsp:All>
</wsp:ExactlyOne>

发送请求的头部:

    <SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1">
        <wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-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="X509-IDXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</wsse:BinarySecurityToken>
        <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-BF463C6BF1D93A74AC14297178534515">
            <ds:SignedInfo>
                <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                    <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="soap"/>
                </ds:CanonicalizationMethod>
                <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                <ds:Reference URI="#_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX">
                    <ds:Transforms>
                        <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                            <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList=""/>
                        </ds:Transform>
                    </ds:Transforms>
                    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                    <ds:DigestValue>XXXXXXXXXXXXXXXXXXXXXXXXXXXX</ds:DigestValue>
                </ds:Reference>
            </ds:SignedInfo>
            <ds:SignatureValue>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</ds:SignatureValue>
            <ds:KeyInfo Id="KI-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX">
                <wsse:SecurityTokenReference wsu:Id="STR-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX">
                    <wsse:Reference URI="#X509-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
                </wsse:SecurityTokenReference>
            </ds:KeyInfo>
        </ds:Signature>
    </wsse:Security>
</SOAP-ENV:Header>

以及答案的标题:

    <soapenv:Header>
    <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <ds:Signature Id="Signature-9821" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <ds:SignedInfo>
                <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                <ds:Reference URI="#id-9822">
                    <ds:Transforms>
                        <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                    </ds:Transforms>
                    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                    <ds:DigestValue>XXXXXXXXXXXXXXXXXXXXXXXXXXX</ds:DigestValue>
                </ds:Reference>
            </ds:SignedInfo>
            <ds:SignatureValue>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</ds:SignatureValue>
            <ds:KeyInfo Id="KeyId-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX">
                <wsse:SecurityTokenReference wsu:Id="STRId-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
                    <ds:X509Data>
                        <ds:X509IssuerSerial>
                            <ds:X509IssuerName>CN=XXXX,OU=XXXX,O=XXX,L=XXXX,ST=XXXXX,C=XX</ds:X509IssuerName>
                            <ds:X509SerialNumber>XXXXXXXXX</ds:X509SerialNumber>
                        </ds:X509IssuerSerial>
                    </ds:X509Data>
                </wsse:SecurityTokenReference>
            </ds:KeyInfo>
        </ds:Signature>
    </wsse:Security>
</soapenv:Header>

20015 年 5 月 6 日编辑:

因此,在使用传入响应调试 X509TokenPolicyValidator(由 Colm 建议)后,我们发现以下内容:

  • bstResults 为空
  • signedResults 包含一个值
  • referenceType 是 ISSUER_SERIAL不是 KEY_IDENTIFIER(第 172 行,->> x509-reference-type=ISSUER_SERIAL)
  • signatureElement 将为 null(第 175 行,->> token-element=[ds:Signature: null])

X509TokenPolicyValidator.java 的代码片段:

168         // Maybe the X.509 token was included as a KeyIdentifier
169         if (X509_V3_VALUETYPE.equals(requiredType)) {
170             for (WSSecurityEngineResult result : signedResults) {
171                 STRParser.REFERENCE_TYPE referenceType = 
172                     (STRParser.REFERENCE_TYPE)result.get(WSSecurityEngineResult.TAG_X509_REFERENCE_TYPE);
173                 if (STRParser.REFERENCE_TYPE.KEY_IDENTIFIER == referenceType) {
174                     Element signatureElement = 
175                         (Element)result.get(WSSecurityEngineResult.TAG_TOKEN_ELEMENT);
176                     Element keyIdentifier = getKeyIdentifier(signatureElement);
177                     if (keyIdentifier != null 
178                         && X509_V3_VALUETYPE.equals(keyIdentifier.getAttributeNS(null, "ValueType"))) {
179                         try {
180                             X509Security token = 
181                                 new X509Security(keyIdentifier, 
182                                                  new BSPEnforcer(true));
183                             X509Certificate cert = token.getX509Certificate(null);
184                             if (cert != null && cert.getVersion() == 3) {
185                                 return true;
186                             }
187                         } catch (WSSecurityException e) {
188                             LOG.log(Level.FINE, e.getMessage());
189                         }
190                     }
191                 }
192             }
193         }
194         return false;  

signedResult:

[{signature-value=[B@259d5279, subject=null, canonicalization-method=http://www.w3.org/2001/10/xml-exc-c14n#, public-key=null, x509-certificates=[Ljava.security.cert.X509Certificate;@3c9e169f, signature-method=http://www.w3.org/2000/09/xmldsig#rsa-sha1, secret=null, principal=CN=xxx, OU=xxx, O=xxx, L=xxx, ST=xxx, C=xxx, data-ref-uris=[org.apache.wss4j.dom.WSDataRef@20326436], x509-reference-type=ISSUER_SERIAL, x509-certificate=[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx], validated-token=true, action=2, id=Signature-3289, token-element=[ds:Signature: null]}, null, null, null, null, null, null, null, null, null]

【问题讨论】:

    标签: web-services soap cxf ws-security


    【解决方案1】:

    BinarySecurityToken 中的证书可能不是“v3”X509Certificate(如“WssX509V3Token10”策略所示),而是“v1”。

    科尔姆。

    【讨论】:

    • 感谢您的意见。但是,Windows 和 keytool 都报告涉及的每个证书的 V3 证书。但是,它们的扩展名不同。我需要特殊的扩展名/扩展名值来允许数字签名吗?
    • 不需要特殊的扩展。我用最新的 CXF 代码测试了类似的消息,它工作正常。这里给出了验证证书的逻辑,也许你可以设置一个断点并弄清楚发生了什么?git-wip-us.apache.org/repos/asf?p=cxf.git;a=blob;f=rt/ws/…
    • 我们调试了课程。我用结果编辑了原始问题。从我们的角度来看,这几乎无法解释。也许你能理解它?
    • 好的,我知道问题出在哪里。 IMO 服务响应不正确。服务策略指定 RecipientToken 必须“始终”包含在请求中(并通过 IssuerSerial 引用)。但是,服务响应(或包含证书的 KeyIdentifier)中没有 BinarySecurityToken。 IssuerSerial 只是一种引用证书的方式,不能被视为“包含”。
    • 原来如此,谢谢。如果您想将其发布为答案,那么我很乐意接受。
    猜你喜欢
    • 1970-01-01
    • 2012-02-12
    • 2011-07-03
    • 2018-11-30
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    • 2012-09-20
    • 2011-02-18
    相关资源
    最近更新 更多