簡體   English   中英

驗證SOAP響應xml時間戳和簽名X509 spring-ws-security

[英]Validate SOAP response xml timestamp and signature X509 spring-ws-security

我是spring-ws-security的新手,已經閱讀了google和stacktrace上的幾乎所有文章,但無法正常工作。
我需要驗證響應XML簽名,時間戳,然后檢索數據。 當我跳過驗證時,沒有問題,但是一旦添加驗證代碼,就會收到錯誤消息:

WARN:無法驗證請求:簽名或解密無效; 嵌套的異常是org.apache.ws.security.WSSecurityException:簽名或解密無效

@Configuration
public class SoapClientConfig {

final String generatedResource = "packageName";

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

@Bean
public Wss4jSecurityInterceptor securityInterceptor() throws Exception {
    Wss4jSecurityInterceptor securityInterceptor = new Wss4jSecurityInterceptor();

    // set security actions
    securityInterceptor.setSecurementActions("Timestamp Signature");
    securityInterceptor.setSecurementUsername("clientkeystoreusername");
    securityInterceptor.setSecurementPassword("clientkeystorepassword");

    //sign both body and timestamp - default body will be signed
    securityInterceptor.setSecurementSignatureParts("{}{http://schemas.xmlsoap.org/soap/envelope/}Body;{}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp");

    //This will generate binarySecurityToken in header
    securityInterceptor.setSecurementSignatureKeyIdentifier("DirectReference");
    securityInterceptor.setSecurementSignatureCrypto(getRequestCryptoBean().getObject());

    //This is validation code, which is not validating response.
    securityInterceptor.setValidationActions("Timestamp Signature");
    securityInterceptor.setValidationSignatureCrypto(getResponseCryptoBean().getObject());
    securityInterceptor.setValidationCallbackHandler(securityCallbackHandler());

    return securityInterceptor;
}

@Bean
public CryptoFactoryBean getRequestCryptoBean() throws IOException, URISyntaxException {

    CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
    cryptoFactoryBean.setKeyStorePassword("clientkeystorepassword");
    cryptoFactoryBean.setKeyStoreLocation("client.jks");
    return cryptoFactoryBean;
}

@Bean
public CryptoFactoryBean getResponseCryptoBean() throws Exception {

    CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
    cryptoFactoryBean.setDefaultX509Alias("1");
    cryptoFactoryBean.setKeyStorePassword("serverkeystorepassword");
    cryptoFactoryBean.setKeyStoreLocation("server.jks");
    cryptoFactoryBean.afterPropertiesSet();
    return cryptoFactoryBean;
}

@Bean
public Jaxb2Marshaller getMarshaller() {
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setContextPath(generatedResource);
    return marshaller;
}

@Bean
public Card getAvailableCardsClient() throws Exception {
    Card memberCard = new Card();
    memberCard.setMarshaller(getMarshaller());
    memberCard.setUnmarshaller(getMarshaller());

    //Set timeout for soap service
    HttpComponentsMessageSender sender = new HttpComponentsMessageSender();
    sender.setConnectionTimeout(2000);
    sender.setReadTimeout(2000);
    memberCard.setMessageSender(sender);
    //end timeout

    memberCard.setDefaultUri("url");

    //add interceptor for adding and validating signature
    ClientInterceptor[] interceptors = new ClientInterceptor[]{securityInterceptor()};
    memberCard.setInterceptors(interceptors);

    return memberCard;
}

}

** server.jks包含服務器的公鑰。 而且此身份驗證也是X509證書。 請幫助我弄清楚如何驗證響應。

我找到了解決方案,並為其他在同一條船上的其他人發布了信息。

在我的方案中,由於必須使用兩個不同的證書(server.jks,client.jks)來進行請求和響應驗證; 我不能為此使用相同的攔截器。 我最終創建了兩種不同的攔截器,一種用於請求,另一種用於響應。

這是工作代碼副本:

@Configuration
public class SoapClientConfig {

    @Bean
    public KeyStoreCallbackHandler securityCallbackHandler() throws Exception {
        KeyStoreCallbackHandler callbackHandler = new KeyStoreCallbackHandler();
        callbackHandler.setSymmetricKeyPassword("serverPassword");
        return callbackHandler;
    }

    @Bean
    public Wss4jSecurityInterceptor securityInterceptor() throws IOException, Exception {

        Wss4jSecurityInterceptor securityInterceptor = new Wss4jSecurityInterceptor();

        // set security actions
        securityInterceptor.setSecurementActions("Timestamp Signature");
        securityInterceptor.setSecurementUsername("clientAias");
        securityInterceptor.setSecurementPassword("clientPassword");

        //sign both body and timestamp - default body will be signed
        securityInterceptor.setSecurementSignatureParts("{}{http://schemas.xmlsoap.org/soap/envelope/}Body;{}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp");

        //This will generate binarySecurityToken in header
        securityInterceptor.setSecurementSignatureKeyIdentifier("DirectReference");
        securityInterceptor.setSecurementSignatureCrypto(getRequestCryptoBean().getObject());

        return securityInterceptor;
    }

    @Bean
    public CryptoFactoryBean getRequestCryptoBean() throws IOException {

        CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
        cryptoFactoryBean.setKeyStorePassword("clientPassword");
        cryptoFactoryBean.setKeyStoreLocation("clientCertLoc");
        return cryptoFactoryBean;
    }

    @Bean
    public Wss4jSecurityInterceptor responseSecurityInterceptor() throws IOException, Exception {

        Wss4jSecurityInterceptor securityInterceptor = new Wss4jSecurityInterceptor();
        securityInterceptor.setValidationActions("Timestamp Signature");
        securityInterceptor.setValidationSignatureCrypto(getResponseCryptoBean().getObject());
        securityInterceptor.setValidationCallbackHandler(securityCallbackHandler());

        return securityInterceptor;
    }

    @Bean
    public CryptoFactoryBean getResponseCryptoBean() throws Exception {

        CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
        cryptoFactoryBean.setKeyStoreLocation("serverCertLoc");
        cryptoFactoryBean.setDefaultX509Alias("serverAlias");
        cryptoFactoryBean.setKeyStorePassword("serverPassword");
        cryptoFactoryBean.afterPropertiesSet();
        return cryptoFactoryBean;
    }

    @Bean
    public Jaxb2Marshaller getMarshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath(generatedResource);
        return marshaller;
    }

    @Bean
    public WebServiceClass getPojoClassMethod() throws ConnectException, Exception {

        WebServiceClass pClass= new WebServiceClass();
        pClass.setMarshaller(getMarshaller());
        pClass.setUnmarshaller(getMarshaller());

        //Set timeout for soap service
        HttpComponentsMessageSender sender = new HttpComponentsMessageSender();
        int timeout;
        if (null == stringFromEnvironmentOrIllegalStateException(env, timeoutInMs)) {
            timeout = 10000;
        } else {
            timeout = Integer.parseInt(stringFromEnvironmentOrIllegalStateException(env, timeoutInMs));
        }
        sender.setConnectionTimeout(timeout);
        sender.setReadTimeout(timeout);
        pClass.setMessageSender(sender);
        //end timeout config

        pClass.setDefaultUri("actionURL");
        ClientInterceptor[] interceptors = new ClientInterceptor[]{securityInterceptor(), responseSecurityInterceptor()};
        pClass.setInterceptors(interceptors);

        return pClass;
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM