首页 > 解决方案 > 带有 ws-security 的肥皂信封在响应中包含两个 DigestValue

问题描述

我有一个使用 SOAP 1.2 和 WS-Security 的 Spring Boot 项目,但我无法弄清楚为什么响应包含两个 DigestValue,据我所知,它应该只有一个......这是当前的 ws-security 配置:

import java.io.IOException;
import java.util.List;

import org.apache.wss4j.common.crypto.Crypto;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.ws.config.annotation.WsConfigurationSupport;
import org.springframework.ws.server.EndpointInterceptor;
import org.springframework.ws.soap.security.wss4j2.callback.KeyStoreCallbackHandler;
import org.springframework.ws.soap.security.wss4j2.support.CryptoFactoryBean;

@Configuration
public class WSSecurityConfig extends WsConfigurationSupport {

@Value("${wssecurity.key-store}")
private String keystoreLocation;

@Value("${wssecurity.key-store-password}")
private String keystorePassword;

@Value("${wssecurity.server-certificate-alias}")
private String serverCertificateAlias;

@Value("${wssecurity.server-certificate-password}")
private String serverCertificatePassword;

@Value("${wssecurity.client-public-key}")
private String clientPublicKeyAlias;

/***Definizione del WS-Security Interceptor***/
@Bean
public CustomEndpointInterceptor wssecurityEndpointInterceptor() throws Exception {
    CustomEndpointInterceptor customSmartEndpointInterceptor = new CustomEndpointInterceptor();

    // validate incoming request       
    customSmartEndpointInterceptor.setValidationActions( "Signature" );
    CryptoFactoryBean bean = getCryptoFactoryBean();
    Crypto crypto = bean.getObject();
    customSmartEndpointInterceptor.setValidationSignatureCrypto( crypto );
    customSmartEndpointInterceptor.setValidationDecryptionCrypto( getCryptoFactoryBean().getObject());
    customSmartEndpointInterceptor.setValidationCallbackHandler( securityCallbackHandler() );

    // sign the response        
    customSmartEndpointInterceptor.setSecurementActions( "Signature" );
    customSmartEndpointInterceptor.setSecurementUsername( serverCertificateAlias );
    customSmartEndpointInterceptor.setSecurementPassword( serverCertificatePassword );
    customSmartEndpointInterceptor.setSecurementSignatureKeyIdentifier( "DirectReference" );      

    customSmartEndpointInterceptor.setSecurementSignatureCrypto( getCryptoFactoryBean().getObject() );

    return customSmartEndpointInterceptor;
}

@Bean
public CryptoFactoryBean getCryptoFactoryBean() throws IOException {
    CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
    cryptoFactoryBean.setKeyStorePassword( keystorePassword );       .
    cryptoFactoryBean.setKeyStoreLocation( new ClassPathResource( keystoreLocation ) );
    return cryptoFactoryBean;
}

@Override
public void addInterceptors( List<EndpointInterceptor> interceptors ) {
    try {
        CustomEndpointInterceptor interceptor = wssecurityEndpointInterceptor();
        interceptors.add( interceptor );
    } catch ( Exception e ) {
        throw new RuntimeException( "could not initialize security interceptor" );
    }
}

@Bean
public KeyStoreCallbackHandler securityCallbackHandler() {
    KeyStoreCallbackHandler callbackHandler = new KeyStoreCallbackHandler();
    callbackHandler.setPrivateKeyPassword( serverCertificatePassword );
    return callbackHandler;
}
}

这是一个示例响应:

<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<env:Header>
  <wsse:Security env:mustUnderstand="true" 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">
     <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-dfd95ba9-b1a1-49a6-8277-2075c101619e">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</wsse:BinarySecurityToken>
     <ds:Signature Id="SIG-98b69df3-1410-42b0-8947-e6d9a07d15c3" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:SignedInfo>
           <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
              <ec:InclusiveNamespaces PrefixList="env" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
           </ds:CanonicalizationMethod>
           <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
           <ds:Reference URI="#id-7a0a7c84-5537-4311-8798-0445e88048f6">
              <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>aWqZez1xvQv4hBRBXtMpJDHYWxw=</ds:DigestValue>
           </ds:Reference>
           <ds:Reference URI="#SC-cb19653f-2eab-42a6-93cf-e66efab96f85">
              <ds:Transforms>
                 <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                    <ec:InclusiveNamespaces PrefixList="wsse env" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                 </ds:Transform>
              </ds:Transforms>
              <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
              <ds:DigestValue>7v6BHKD7kICPCPwPVPl7fZ57p7o=</ds:DigestValue>
           </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>Fwi8qjIVMnpT8Kb1uqHuuwS4aVFUenVleZflrtTth3xVpRnvtKqHJYQlNf1kWUvpdFlQrVxnQX5Ob6dukmEBnYlmbfDMBN2IMnqTchpe9GD+fUNkT2mcdMwLuaUOCp4cXjWTGL/T4IiRqnT66N1Tb1SwA1VKwO4YqfRB48KDh0oP/tgmFogFBpPowEuEf3GwQKJsE5k7Cbuy3g4PtdJ8woBulJGSU5FL7evqNeJwSEXgmhOEOohsGjf2/Uzr3fR60OpZXv+aHIV3NgDYe4FSCM4l/CfE7sOfh0DL6xYTzXSQxN6LDEu0gH7P0GiBSFLH85mGPhruEAhnIk2agVLWfw==</ds:SignatureValue>
        <ds:KeyInfo Id="KI-1645752f-47f1-45d7-b935-6c4060edbeea">
           <wsse:SecurityTokenReference wsu:Id="STR-d21a6c25-bf5f-4530-8f25-b31fd9ba2e72">
              <wsse:Reference URI="#X509-dfd95ba9-b1a1-49a6-8277-2075c101619e" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
           </wsse:SecurityTokenReference>
        </ds:KeyInfo>
     </ds:Signature>
     <wsse11:SignatureConfirmation Value="HLhw/SB6gct2G+tr5cW5S6HrX80O1cCEfdtBAd22CMWqBJPVvlSJtB04uxRxUoAnEWx88GmAlpl9Tb89x/gnw+6qIsf8VYej5GeQdJi9Y2XSTkPy5Auy2ZmnOtl1UFzEKrLFZochffRf7oKEJjNs4VcWF6CflnNL6Wg3dQ0GZw03/mMYphn/N07lCivUdy4nuEGEu6qsbF/OvNI/fIC8Y7gby79Ooc0gAmg7Riwv7vGBShhZxTLZ0n3cTmbol7FcZifZLQcVz9rUmIldnslDupyAQHJWlEUruYovk8NpEPNljKEMZO2EmOMFnM3mNu5wUnb75Dui2MRI7IYd8a8iEg==" wsu:Id="SC-cb19653f-2eab-42a6-93cf-e66efab96f85" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"/>
  </wsse:Security>
</env:Header>

为什么响应中有两个不同的 DigestValue?不应该只有一个吗?

提前致谢。

标签: javaspring-bootsoapws-security

解决方案


好的,我知道了。

springboot中使用了一个flag,默认设置为TRUE(这个flag实际上是WSS4J中的一个默认,springboot使用的)。此标志启用签名确认,它是响应中双 DigestValue 的原因。为了禁用它,我只需要添加这一行:

customSmartEndpointInterceptor.setEnableSignatureConfirmation( false );

在我的 wssecurityEndpointInterceptor() 方法中


推荐阅读