基于Spring-WS的SOAP服务WS-Security签名验证与响应签名问题
Spring Boot SOAP服务WS-Security签名验证与响应签名实现问题
需求背景
需创建遵循WS-Security标准的SOAP服务,实现请求签名验证与响应签名功能,供SOAP客户端调用,核心要求是在SOAP信封的soap:Header中传递证书。
现有资源
- Java 17 + Spring Boot 3.3.3开发的SOAP服务
- 客户端请求签名用的
.cer证书文件 - 我方的
.cer证书与.key私钥文件 - 通过指令生成的
.p12和.jks密钥库文件
已尝试方案及问题
方案1:使用Wss4jSecurityInterceptor
生成的代码存在虚构方法或不符合需求,查阅Spring-WS文档未明确参数来源与计算方式。结合crypto.properties文件与包含我方证书、私钥的.p12/.jks文件(密码与别名有效)时,出现“unrecognized character 111”或库初始化失败等错误,导致服务无法启动,或返回202响应且无响应体。
方案2:自定义SoapEndpointInterceptor处理消息
严格参照相关文档手动构建WS-Security标签:
BinarySecurityToken:将.cer证书通过X.509Certificate类转为Base64填入DigestMethod与SignatureMethod分别使用SHA-1、SHA-1withRSADigestValue:对soap:Body内根元素XML内容生成SHA-1哈希值SignatureValue:从.p12文件提取私钥,对SignedInfo元素的完整XML字符串签名
同时设置UUID生成的ID与关联URI、有效期1小时的Timestamp。但客户端验证响应时始终提示“signature is invalid”,更换自签名证书、CA签发证书均无改善,且已确认双方.cer证书一致。
补充需求
- 实现服务调用其他SOAP服务时,对请求签名并验证响应签名
- 在
soap:Header中添加自定义XML元素
当前接近可行的代码(服务可启动但客户端无法识别)
@Configuration @EnableWs public class SoapService extends WsConfigurerAdapter { // other soap-service-related beans like message dispatcher, marshaller, and so on. @Bean Wss4jSecurityInterceptor securityInterceptor() { Wss4jSecurityInterceptor interceptor = new Wss4jSecurityInterceptor(); try { // check incoming certificate, this does produce an output similar to the ones on my cites, but not equal interceptor.setSecurementActions(WSHandlerConstants.SIGNATURE); interceptor.setValidationCallbackHandler(this.securityCallback()); // sign outgoing response interceptor.setSecurementActions(WSHandlerConstants.SIGNATURE); interceptor.setSecurementUsername("your_alias"); interceptor.setSecurementPassword("your_password"); interceptor.setSecurementSignatureCrypto(this.cryptoConfig().getObject()); } catch(Exception e) { e.printStackTrace(); System.out.println("error while initializing interceptor"); } return interceptor; } @Bean CryptoFactoryBean cryptoConfig() throws IOException { CryptoFactoryBean bean = new CryptoFactoryBean(); bean.setKeyStorePassword("your_password"); bean.setKeyStoreLocation(new ClassPathResource("certificate.jks")); return bean; } @Bean CallbackHandler securityCallback() { // how am i supposed to check the .cer my client sends here? return new SimplePasswordValidationCallbackHandler() {{ setUsers(new Properties() { private static final long serialVersionUID = 3422928594124631515L; { setProperty("alias", "your_password"); } }); }}; } @Override public void addInterceptors(List<EndpointInterceptor> interceptors) { interceptors.add(securityInterceptor()); } }
疑问
- 上述代码是否正确?
- 如何验证客户端发送的
.cer证书?
内容的提问来源于stack exchange,提问作者user13749429
相关产品推荐
相关产品推荐

