前言:
此时咱们对“apachecxf文件”可能比较关心,咱们都需要知道一些“apachecxf文件”的相关文章。那么小编也在网摘上网罗了一些有关“apachecxf文件””的相关资讯,希望咱们能喜欢,各位老铁们一起来了解一下吧!一、前言
上一篇已经完整的讲解了Spring Boot 整合CXF实现SSL会话的整个流程,在此基础上将继续讲解基于SSL会话的签名和验签功能实现。
项目源码:
spring-cxf参考源码:
spring-ws参考源码:
二、开发环境
IDE::IDEA
JDK:1.8
maven:3.6.2
spring boot:2.4.0
cxf:3.4.1
三、实现步骤
具体代码实现参考整合CXF添加日志拦截器样。本章在之前基础上讲解新增内容。
3.1、实现服务端和客户端
新建服务端和客户端spring-cxf-client-signature,spring-cxf-server-signature,并完成服务部署和客户端访问接口,具体步骤见上一篇。
3.2、添加security依赖
spring boot与cxf整合后要进行验签和加解密也只需引入cxf-rt-ws-security,并实现相关配置即可。
服务端、客服端pom文件中添加cxf依赖包
<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-ws-security</artifactId> <version>3.4.1</version></dependency>
3.3、服务端配置加解密及验签信息
在服务端配置类中定义入参和出参的加解密拦截器配置
package org.ouyushan.cxf.config;import org.apache.cxf.Bus;import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;import org.apache.cxf.ext.logging.LoggingInInterceptor;import org.apache.cxf.ext.logging.LoggingOutInterceptor;import org.apache.cxf.jaxws.EndpointImpl;import org.apache.cxf.transport.servlet.CXFServlet;import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;import org.apache.wss4j.dom.handler.WSHandlerConstants;import org.ouyushan.cxf.component.ServerPasswordCallback;import org.ouyushan.cxf.service.UserService;import org.springframework.beans.factory.annotation.Value;import org.springframework.boot.web.servlet.ServletRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import javax.annotation.Resource;import javax.xml.ws.Endpoint;import java.util.HashMap;import java.util.Map;/** * @Description: 服务端配置类 * @Author: ouyushan * @Email: ouyushan@hotmail.com * @Date: 2020/12/03 14:38 */@Configurationpublic class CxfServerConfig { @Value("${client.keyAlias}") private String keyAlias; @Value("${client.trustAlias}") private String trustAlias; @Resource private Bus bus; @Resource private UserService userService; @Bean public ServletRegistrationBean cxfServlet() { return new ServletRegistrationBean(new CXFServlet(), "/ws/*"); } @Bean public Endpoint userEndpoint() { EndpointImpl endpoint = new EndpointImpl(bus, userService); endpoint.publish("/user"); // log the request and response messages endpoint.getInInterceptors().add(loggingInInterceptor()); endpoint.getOutInterceptors().add(loggingOutInterceptor()); // add the WSS4J IN interceptor to verify the signature on the response message endpoint.getInInterceptors().add(serverWssIn()); // add the WSS4J OUT interceptor to sign the request message endpoint.getOutInterceptors().add(serverWssOut()); return endpoint; } @Bean public LoggingInInterceptor loggingInInterceptor() { return new LoggingInInterceptor(); } @Bean public LoggingOutInterceptor loggingOutInterceptor() { return new LoggingOutInterceptor(); } /** * 以下为服务REQ_IN、REQ_OUT的加解密和验签配置 * * @return */ @Bean public Map<String, Object> serverInProps() { Map<String, Object> serverInProps = new HashMap<>(); serverInProps.put(WSHandlerConstants.ACTION, /*WSHandlerConstants.TIMESTAMP + " " +*/ WSHandlerConstants.SIGNATURE); serverInProps.put(WSHandlerConstants.SIGNATURE_USER, keyAlias); serverInProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ServerPasswordCallback.class.getName()); // 验签 serverInProps.put(WSHandlerConstants.SIG_PROP_FILE, "server_trust.properties"); return serverInProps; } @Bean public Map<String, Object> serverOutProps() { Map<String, Object> serverOutProps = new HashMap<>(); serverOutProps.put(WSHandlerConstants.ACTION, /*WSHandlerConstants.TIMESTAMP + " " +*/ WSHandlerConstants.SIGNATURE); serverOutProps.put(WSHandlerConstants.SIGNATURE_USER, trustAlias); serverOutProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ServerPasswordCallback.class.getName()); // 签名 serverOutProps.put(WSHandlerConstants.SIG_PROP_FILE, "server_key.properties"); return serverOutProps; } @Bean public WSS4JInInterceptor serverWssIn() { WSS4JInInterceptor serverWssIn = new WSS4JInInterceptor(); serverWssIn.setProperties(serverInProps()); return serverWssIn; } @Bean public WSS4JOutInterceptor serverWssOut() { WSS4JOutInterceptor serverWssOut = new WSS4JOutInterceptor(); serverWssOut.setProperties(serverOutProps()); return serverWssOut; }}
加解密及验签拦截器属性信息配置
server_key.properties
org.apache.wss4j.crypto.provider=org.apache.wss4j.common.crypto.Merlinorg.apache.wss4j.crypto.merlin.keystore.type=PKCS12org.apache.wss4j.crypto.merlin.keystore.private.password=ouyushan.passorg.apache.wss4j.crypto.merlin.keystore.alias=webserverorg.apache.wss4j.crypto.merlin.keystore.password=ouyushan.passorg.apache.wss4j.crypto.merlin.keystore.file=jks/webserver.p12
server_trust.properties
org.apache.wss4j.crypto.provider=org.apache.wss4j.common.crypto.Merlinorg.apache.wss4j.crypto.merlin.keystore.type=PKCS12org.apache.wss4j.crypto.merlin.keystore.private.password=ouyushan.passorg.apache.wss4j.crypto.merlin.keystore.alias=webclientorg.apache.wss4j.crypto.merlin.keystore.password=ouyushan.passorg.apache.wss4j.crypto.merlin.keystore.file=jks/webclient.p12
密码回调方法实现类ServerPasswordCallback:
package org.ouyushan.cxf.component;import org.apache.wss4j.common.ext.WSPasswordCallback;import org.springframework.stereotype.Component;import javax.security.auth.callback.Callback;import javax.security.auth.callback.CallbackHandler;/** * @Description: 设置回调密码 * @Author: ouyushan * @Email: ouyushan@hotmail.com * @Date: 2020/12/03 16:03 */@Componentpublic class ServerPasswordCallback implements CallbackHandler { /** * 自定义实现业务逻辑 * * @param callbacks */ @Override public void handle(Callback[] callbacks) { WSPasswordCallback callback = (WSPasswordCallback) callbacks[0]; callback.setPassword("ouyushan.pass"); }}3.4、客户端配置加解密及验签信息
CxfClientConfig.java
在服务端配置类中定义入参和出参的加解密拦截器配置
package org.ouyushan.cxf.config;import org.apache.cxf.ext.logging.LoggingInInterceptor;import org.apache.cxf.ext.logging.LoggingOutInterceptor;import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;import org.apache.wss4j.dom.handler.WSHandlerConstants;import org.ouyushan.cxf.component.ClientPasswordCallback;import org.ouyushan.cxf.ws.UserService;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.util.HashMap;import java.util.Map;/** * @Description: * @Author: ouyushan * @Email: ouyushan@hotmail.com * @Date: 2020/11/26 16:52 */@Configurationpublic class CxfClientConfig { @Value("${client.keyAlias}") private String keyAlias; @Value("${client.trustAlias}") private String trustAlias; @Value("${server.serviceUrl}") private String serviceUrl; @Bean public UserService userService() { JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean(); jaxWsProxyFactoryBean.setServiceClass(UserService.class); jaxWsProxyFactoryBean.setAddress(serviceUrl); // log the request and response messages jaxWsProxyFactoryBean.getInInterceptors().add(loggingInInterceptor()); jaxWsProxyFactoryBean.getOutInterceptors().add(loggingOutInterceptor()); // add the WSS4J OUT interceptor to sign the request message jaxWsProxyFactoryBean.getOutInterceptors().add(clientWssOut()); //jaxWsProxyFactoryBean.getOutInterceptors().add(new SAAJOutInterceptor()); // add the WSS4J IN interceptor to verify the signature on the response message jaxWsProxyFactoryBean.getInInterceptors().add(clientWssIn()); //jaxWsProxyFactoryBean.getInInterceptors().add(new SAAJInInterceptor()); UserService userService = (UserService) jaxWsProxyFactoryBean.create(); return userService; } @Bean public LoggingInInterceptor loggingInInterceptor() { return new LoggingInInterceptor(); } @Bean public LoggingOutInterceptor loggingOutInterceptor() { return new LoggingOutInterceptor(); } @Bean public Map<String, Object> clientOutProps() { Map<String, Object> clientOutProps = new HashMap<>(); clientOutProps.put(WSHandlerConstants.ACTION, /*WSHandlerConstants.TIMESTAMP + " " +*/ WSHandlerConstants.SIGNATURE); clientOutProps.put(WSHandlerConstants.SIGNATURE_USER, keyAlias); clientOutProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientPasswordCallback.class.getName()); // 签名 clientOutProps.put(WSHandlerConstants.SIG_PROP_FILE, "client_key.properties"); return clientOutProps; } @Bean public WSS4JOutInterceptor clientWssOut() { WSS4JOutInterceptor clientWssOut = new WSS4JOutInterceptor(); clientWssOut.setProperties(clientOutProps()); return clientWssOut; } @Bean public Map<String, Object> clientInProps() { Map<String, Object> clientInProps = new HashMap<>(); clientInProps.put(WSHandlerConstants.ACTION, /*WSHandlerConstants.TIMESTAMP + " " +*/ WSHandlerConstants.SIGNATURE); clientInProps.put(WSHandlerConstants.SIGNATURE_USER, trustAlias); clientInProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientPasswordCallback.class.getName()); // 验签 clientInProps.put(WSHandlerConstants.SIG_PROP_FILE, "client_trust.properties"); return clientInProps; } @Bean public WSS4JOutInterceptor clientWssIn() { WSS4JOutInterceptor clientWssIn = new WSS4JOutInterceptor(); clientWssIn.setProperties(clientInProps()); return clientWssIn; }}
加解密及验签拦截器属性信息配置
client_trust.properties
org.apache.wss4j.crypto.provider=org.apache.wss4j.common.crypto.Merlinorg.apache.wss4j.crypto.merlin.keystore.type=PKCS12org.apache.wss4j.crypto.merlin.keystore.private.password=ouyushan.passorg.apache.wss4j.crypto.merlin.keystore.alias=webserverorg.apache.wss4j.crypto.merlin.keystore.password=ouyushan.passorg.apache.wss4j.crypto.merlin.keystore.file=jks/webserver.p12
client_key.properties
org.apache.wss4j.crypto.provider=org.apache.wss4j.common.crypto.Merlinorg.apache.wss4j.crypto.merlin.keystore.type=PKCS12org.apache.wss4j.crypto.merlin.keystore.private.password=ouyushan.passorg.apache.wss4j.crypto.merlin.keystore.alias=webclientorg.apache.wss4j.crypto.merlin.keystore.password=ouyushan.passorg.apache.wss4j.crypto.merlin.keystore.file=jks/webclient.p12
密码回调方法实现类ClientPasswordCallback:
package org.ouyushan.cxf.component;import org.apache.wss4j.common.ext.WSPasswordCallback;import org.springframework.stereotype.Component;import javax.security.auth.callback.Callback;import javax.security.auth.callback.CallbackHandler;/** * @Description: 设置回调密码 * @Author: ouyushan * @Email: ouyushan@hotmail.com * @Date: 2020/12/03 16:03 */@Componentpublic class ClientPasswordCallback implements CallbackHandler { /** * 自定义实现业务逻辑 * * @param callbacks */ @Override public void handle(Callback[] callbacks) { WSPasswordCallback callback = (WSPasswordCallback) callbacks[0]; callback.setPassword("ouyushan.pass"); }}
application.yml
server: port: 7070 serviceUrl: : keyAlias: webclient trustAlias: webserver3.4、功能验证
分别启动服务端和客户端,访问客户端请求接口:
客户端控制台输出如下:
2020-12-08 13:46:36.813 INFO 1928 --- [nio-7070-exec-1] o.a.cxf.services.UserService.REQ_OUT : REQ_OUT Address: HttpMethod: POST Content-Type: text/xml ExchangeId: 61972ff8-df54-45f9-af4a-f5fc5b338156 ServiceName: UserServiceService PortName: UserServicePort PortTypeName: UserService Headers: {SOAPAction="", Accept=*/*} Payload: <soap:Envelope xmlns:soap=";><soap:Header><wsse:Security xmlns:wsse="; xmlns:wsu="; soap:mustUnderstand="1"><ds:Signature xmlns:ds="; Id="SIG-8d966868-dd6e-4802-a301-eb2232357ab3"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm=";><ec:InclusiveNamespaces xmlns:ec="; PrefixList="soap"/></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm=";/><ds:Reference URI="#id-dbf085d0-453d-42b8-8c45-e011704fb15c"><ds:Transforms><ds:Transform Algorithm=";/></ds:Transforms><ds:DigestMethod Algorithm=";/><ds:DigestValue>7YUMFs3792vDX3W2fTtWXzejCMI=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>OYYq87+D7mF7NIo05CVpP0+K7bpHWgRhDU5YkstkvmUOJXctY/yt0+jgPJ9u6hIIddwN45nAuFTcV1sGqyc403D1WyZYVyW3M0jK53VTLDGIex++D2rTh+g/stYd05QTfaQlrBUz5PiZoQOCm53zhnAdt2j+5UaRQMPC1aqeSCSZWjkunbDqYwRyY2opHBPVNC2J+3SYaEN9mP8AxJP7mTlGqUAR53SFKoTvwOkbaRtwJ4TJXt6oBO7VV1SgCrRVgiWcBzOtaPLFnqKWutjWYz1CSdW3hvWDZu36NB9k3nuph4G27HHOb0AKQnDG8vUDGg+essChtXBhmPgc+9tO1Q==</ds:SignatureValue><ds:KeyInfo Id="KI-dff1133f-e849-4163-9a09-955606f35c15"><wsse:SecurityTokenReference xmlns:wsse="; xmlns:wsu="; wsu:Id="STR-ec4117ae-cb91-4228-b346-3846cd5926c6"><ds:X509Data><ds:X509IssuerSerial><ds:X509IssuerName>CN=webclient,OU=ouyushan,O=ouyushan,L=beijing,ST=beijing,C=CN</ds:X509IssuerName><ds:X509SerialNumber>1417430396</ds:X509SerialNumber></ds:X509IssuerSerial></ds:X509Data></wsse:SecurityTokenReference></ds:KeyInfo></ds:Signature></wsse:Security></soap:Header><soap:Body xmlns:wsu="; wsu:Id="id-dbf085d0-453d-42b8-8c45-e011704fb15c"><ns2:getUserName xmlns:ns2=";><userId>1</userId></ns2:getUserName></soap:Body></soap:Envelope>2020-12-08 13:46:39.088 WARN 1928 --- [nio-7070-exec-1] o.a.cxf.phase.PhaseInterceptorChain : Skipping interceptor org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor$SAAJOutEndingInterceptor: Phase pre-protocol-ending specified does not exist.2020-12-08 13:46:39.342 INFO 1928 --- [nio-7070-exec-1] o.a.cxf.services.UserService.RESP_IN : RESP_IN Address: Content-Type: text/xml;charset=UTF-8 ResponseCode: 200 ExchangeId: 61972ff8-df54-45f9-af4a-f5fc5b338156 ServiceName: UserServiceService PortName: UserServicePort PortTypeName: UserService Headers: {Keep-Alive=timeout=60, connection=keep-alive, content-type=text/xml;charset=UTF-8, Content-Length=2343, Date=Tue, 08 Dec 2020 05:46:39 GMT} Payload: <soap:Envelope xmlns:soap=";><soap:Header><wsse:Security xmlns:wsse="; xmlns:wsu="; soap:mustUnderstand="1"><ds:Signature xmlns:ds="; Id="SIG-d20e91d6-895b-4813-ae50-461b487895f6"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm=";><ec:InclusiveNamespaces xmlns:ec="; PrefixList="soap"/></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm=";/><ds:Reference URI="#id-78245bbb-fd1b-4b76-b878-5fdcf02bbcb6"><ds:Transforms><ds:Transform Algorithm=";/></ds:Transforms><ds:DigestMethod Algorithm=";/><ds:DigestValue>H3Gcn4FEcctHT4b7BRlUTLjSs44=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>GXaBUSoZPTxsoVWMwd5oXBhYr8LSGCG3R3TgxPWIRnz4kqLUyR47X/l+iAATLJPa4GoLPZeTzGxChcx9F024/HuVZLU9mQ2KNIQqgkfssbOd7kv71/9wrROK4mdefx8sMsNHC9Z8E/DEpNgBlJJE4UpeBxBvfqI/6ESoi+xys/0CUSqP5WtOSOeG/DbwR+Q8jMIvdAYFArZ9wDk0RIGLaROYSfSu7J3oSeu9gtmRF4O5UazWzktnotVacqlSPMKmz6A9QeAsRd163oNv6EquCOxcp5uPVWr/CNyv/j4ghgYUEH7C2fkUv5UZRYBBK7mRP/m4PHt4tAVgmH9PBKT5Sg==</ds:SignatureValue><ds:KeyInfo Id="KI-c4a46360-fa25-43d8-a617-6f5161cace57"><wsse:SecurityTokenReference xmlns:wsse="; xmlns:wsu="; wsu:Id="STR-40489c37-23fa-4691-b509-d71751d7dedb"><ds:X509Data><ds:X509IssuerSerial><ds:X509IssuerName>CN=webserver,OU=ouyushan,O=ouyushan,L=beijing,ST=beijing,C=CN</ds:X509IssuerName><ds:X509SerialNumber>905289312</ds:X509SerialNumber></ds:X509IssuerSerial></ds:X509Data></wsse:SecurityTokenReference></ds:KeyInfo></ds:Signature></wsse:Security></soap:Header><soap:Body xmlns:wsu="; wsu:Id="id-78245bbb-fd1b-4b76-b878-5fdcf02bbcb6"><ns2:getUserNameResponse xmlns:ns2=";><return>tom</return></ns2:getUserNameResponse></soap:Body></soap:Envelope>
服务端控制台输出如下:
2020-12-08 13:46:38.649 INFO 6812 --- [nio-8080-exec-1] o.a.cxf.services.UserService.REQ_IN : REQ_IN Address: HttpMethod: POST Content-Type: text/xml; charset=UTF-8 ExchangeId: f6631eb5-a99b-4481-ae32-9aac6b603813 ServiceName: UserService PortName: UserServiceImplPort PortTypeName: UserService Headers: {SOAPAction="", Accept=*/*, host=localhost:8080, connection=keep-alive, content-type=text/xml; charset=UTF-8, cache-control=no-cache, Content-Length=2326, pragma=no-cache, user-agent=Apache-CXF/3.4.1} Payload: <soap:Envelope xmlns:soap=";><soap:Header><wsse:Security xmlns:wsse="; xmlns:wsu="; soap:mustUnderstand="1"><ds:Signature xmlns:ds="; Id="SIG-8d966868-dd6e-4802-a301-eb2232357ab3"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm=";><ec:InclusiveNamespaces xmlns:ec="; PrefixList="soap"/></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm=";/><ds:Reference URI="#id-dbf085d0-453d-42b8-8c45-e011704fb15c"><ds:Transforms><ds:Transform Algorithm=";/></ds:Transforms><ds:DigestMethod Algorithm=";/><ds:DigestValue>7YUMFs3792vDX3W2fTtWXzejCMI=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>OYYq87+D7mF7NIo05CVpP0+K7bpHWgRhDU5YkstkvmUOJXctY/yt0+jgPJ9u6hIIddwN45nAuFTcV1sGqyc403D1WyZYVyW3M0jK53VTLDGIex++D2rTh+g/stYd05QTfaQlrBUz5PiZoQOCm53zhnAdt2j+5UaRQMPC1aqeSCSZWjkunbDqYwRyY2opHBPVNC2J+3SYaEN9mP8AxJP7mTlGqUAR53SFKoTvwOkbaRtwJ4TJXt6oBO7VV1SgCrRVgiWcBzOtaPLFnqKWutjWYz1CSdW3hvWDZu36NB9k3nuph4G27HHOb0AKQnDG8vUDGg+essChtXBhmPgc+9tO1Q==</ds:SignatureValue><ds:KeyInfo Id="KI-dff1133f-e849-4163-9a09-955606f35c15"><wsse:SecurityTokenReference xmlns:wsse="; xmlns:wsu="; wsu:Id="STR-ec4117ae-cb91-4228-b346-3846cd5926c6"><ds:X509Data><ds:X509IssuerSerial><ds:X509IssuerName>CN=webclient,OU=ouyushan,O=ouyushan,L=beijing,ST=beijing,C=CN</ds:X509IssuerName><ds:X509SerialNumber>1417430396</ds:X509SerialNumber></ds:X509IssuerSerial></ds:X509Data></wsse:SecurityTokenReference></ds:KeyInfo></ds:Signature></wsse:Security></soap:Header><soap:Body xmlns:wsu="; wsu:Id="id-dbf085d0-453d-42b8-8c45-e011704fb15c"><ns2:getUserName xmlns:ns2=";><userId>1</userId></ns2:getUserName></soap:Body></soap:Envelope>2020-12-08 13:46:39.032 INFO 6812 --- [nio-8080-exec-1] o.a.cxf.services.UserService.RESP_OUT : RESP_OUT Address: Content-Type: text/xml ResponseCode: 200 ExchangeId: f6631eb5-a99b-4481-ae32-9aac6b603813 ServiceName: UserService PortName: UserServiceImplPort PortTypeName: UserService Headers: {} Payload: <soap:Envelope xmlns:soap=";><soap:Header><wsse:Security xmlns:wsse="; xmlns:wsu="; soap:mustUnderstand="1"><ds:Signature xmlns:ds="; Id="SIG-d20e91d6-895b-4813-ae50-461b487895f6"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm=";><ec:InclusiveNamespaces xmlns:ec="; PrefixList="soap"/></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm=";/><ds:Reference URI="#id-78245bbb-fd1b-4b76-b878-5fdcf02bbcb6"><ds:Transforms><ds:Transform Algorithm=";/></ds:Transforms><ds:DigestMethod Algorithm=";/><ds:DigestValue>H3Gcn4FEcctHT4b7BRlUTLjSs44=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>GXaBUSoZPTxsoVWMwd5oXBhYr8LSGCG3R3TgxPWIRnz4kqLUyR47X/l+iAATLJPa4GoLPZeTzGxChcx9F024/HuVZLU9mQ2KNIQqgkfssbOd7kv71/9wrROK4mdefx8sMsNHC9Z8E/DEpNgBlJJE4UpeBxBvfqI/6ESoi+xys/0CUSqP5WtOSOeG/DbwR+Q8jMIvdAYFArZ9wDk0RIGLaROYSfSu7J3oSeu9gtmRF4O5UazWzktnotVacqlSPMKmz6A9QeAsRd163oNv6EquCOxcp5uPVWr/CNyv/j4ghgYUEH7C2fkUv5UZRYBBK7mRP/m4PHt4tAVgmH9PBKT5Sg==</ds:SignatureValue><ds:KeyInfo Id="KI-c4a46360-fa25-43d8-a617-6f5161cace57"><wsse:SecurityTokenReference xmlns:wsse="; xmlns:wsu="; wsu:Id="STR-40489c37-23fa-4691-b509-d71751d7dedb"><ds:X509Data><ds:X509IssuerSerial><ds:X509IssuerName>CN=webserver,OU=ouyushan,O=ouyushan,L=beijing,ST=beijing,C=CN</ds:X509IssuerName><ds:X509SerialNumber>905289312</ds:X509SerialNumber></ds:X509IssuerSerial></ds:X509Data></wsse:SecurityTokenReference></ds:KeyInfo></ds:Signature></wsse:Security></soap:Header><soap:Body xmlns:wsu="; wsu:Id="id-78245bbb-fd1b-4b76-b878-5fdcf02bbcb6"><ns2:getUserNameResponse xmlns:ns2=";><return>tom</return></ns2:getUserNameResponse></soap:Body></soap:Envelope>
从日志可以看出完整的请求链路信息,在客户端REQ_OUT和服务端的REQ_IN的Payload中已包含Signature签名信息,说明签名已经生效。
四、总结
通过本篇教材,您应该已掌握Spring Boot整合CXF实现数字证书签名功能。整个过程可分为三步:
准备相应证书;服务端数字证书签名拦截器;客户端数字证书签名拦截器。
至此Spring Boot 整合CXF实现数字签名已完成,在测试过程中可能会出现用户名为空,证书无法加载等问题,请确保证书信息正确,并配置无误。
标签: #apachecxf文件