Apache CXF - 配置WSS4JInInterceptor

时间:2016-03-17 14:32:57

标签: java soap cxf ws-security

我在连接服务器时在项目中使用Apache CXF + WS-Security。

收到服务器的回复后,我必须使用服务器的公钥验证SignatureConfirmationTimestampSOAP-body的签名,该公钥包含在{{{ SOAP标头中的1}} 之后,我需要使用我自己的证书的私钥解密对称密钥,并最终解密SOAP主体。

以下是请求流程图:

enter image description here

我应该如何配置BinarySecurityToken来做到这一点? 这就是我现在所拥有的:

WSS4JInInterceptor

server_sec.properties

// for outgoing messages: Signature and Timestamp validation
        outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.TIMESTAMP);
        outProps.put(WSHandlerConstants.USER, "sss");
        outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientKeystorePasswordCallbackHandler.class.getName());
        outProps.put(WSHandlerConstants.SIG_PROP_FILE, "client_sec.properties");
        outProps.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
        outProps.put(WSHandlerConstants.SIGNATURE_PARTS, "{}{http://www.w3.org/2003/05/soap-envelope}Body;{}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{}{http://kontaktinfo.difi.no/wsdl/oppslagstjeneste-16-02}Oppslagstjenesten}");
        outProps.put(WSHandlerConstants.SIG_ALGO, "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
        outProps.put(WSHandlerConstants.SIG_DIGEST_ALGO, "http://www.w3.org/2001/04/xmlenc#sha256");


        // for incoming messages: Signature and Timestamp validation. Response is Encrypted
        inProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.ENCRYPT);
        inProps.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
        inProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientKeystorePasswordCallbackHandler.class.getName());
        inProps.put(WSHandlerConstants.SIG_PROP_FILE, "server_sec.properties");
        inProps.put(WSHandlerConstants.DEC_PROP_FILE, "client_sec.properties");

        wss4JInInterceptor = new WSS4JInInterceptor(inProps);
        wss4JOutInterceptor = new WSS4JOutInterceptor(outProps);

client_sec.properties:

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=changeit
org.apache.ws.security.crypto.merlin.keystore.alias=test
org.apache.ws.security.crypto.merlin.file=certs/server.jks

收到回复后,我收到错误:

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=PKCS12
org.apache.ws.security.crypto.merlin.keystore.password=changeit
org.apache.ws.security.crypto.merlin.keystore.alias=sss
org.apache.ws.security.crypto.merlin.file=certs/sss_client.p12

我看到的第一个问题是CXF希望服务器证书是一个keystone文件,但我将它作为响应中包含的二进制安全令牌。当然,不能将它提取到文件中。

我应该如何配置我的InInterceptor以便它可以验证和解密服务器的响应?

更新1:

  • 根CA证书已添加到SEVERE: Servlet.service() for servlet [rest] in context with path [] threw exception [Request processing failed; nested exception is javax.xml.ws.soap.SOAPFaultException: Error during certificate path validation: No trusted certs found] with root cause org.apache.wss4j.common.ext.WSSecurityException: Error during certificate path validation: No trusted certs found at org.apache.wss4j.common.crypto.Merlin.verifyTrust(Merlin.java:780) at org.apache.wss4j.dom.validate.SignatureTrustValidator.verifyTrustInCerts(SignatureTrustValidator.java:108) at org.apache.wss4j.dom.validate.SignatureTrustValidator.validate(SignatureTrustValidator.java:64) at org.apache.wss4j.dom.processor.SignatureProcessor.handleToken(SignatureProcessor.java:189) at org.apache.wss4j.dom.engine.WSSecurityEngine.processSecurityHeader(WSSecurityEngine.java:344) at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessageInternal(WSS4JInInterceptor.java:280) at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:184) at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:93) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:798) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1670) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1551) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1348) at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:56) at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:216) at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:651) at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:514) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:324) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:277) at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96) at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139) at com.sun.proxy.$Proxy74.getPeople(Unknown Source) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745)

  • 中间证书位于使用的密钥库中 在拦截

以下是我尝试验证和解密的服务器响应:

JRE/lib/security/cacerts

0 个答案:

没有答案