在JBOSS 7中使用CXF WS实现X509的问题



我已经使用JBOSS在CXF中创建了一个WS,我的要求是我想启用X509证书和使用CXF客户端调用WS。我能够创建WS,并能够调用它客户端成功,但当我实现X509我得到错误:-"由:java.lang.ClassNotFoundException: org.apache.cxf.jaxws.EndpointImpl从[模块"deploy .cxfpoc。war:main" from Service Module Loader]",下面是相同的细节。

我的环境:

Application Server: JBOSS-AS7.1.1.FinalJAVA: 1.7

对于X509实现,我遵循以下步骤:

1)生成私钥与testUser/testPass在keystore

keytool -genkey -alias testUser -keypass testPass -keystore privateststore .jks-storepass changeit -dname "cn=testUser" -keyalg RSA

2)自签名证书

keytool -selfcert -alias testUser -keystore privatestore。jks -storepass change -keypass testPass

3)

keytool -export -alias testUser -file key。Rsa -keystore privatestore。JKS -storepass changeit

4)生成公钥库

keytool -import -alias testUser -file key。Rsa -keystore publicstore。JKS -storepass changeit

现在我已经复制了publicstore。在服务器的WEB-INF/classes文件夹中复制jks文件服务器。属性文件:

server.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.file=publicstore.jks
下面是Web Service的代码:

Web服务的服务器源

package ws;
import java.util.HashMap;
import java.util.Map;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
import org.apache.ws.security.handler.WSHandlerConstants;
@WebService(name = "DemoCXF", serviceName = "DemoCXFService", portName = "DemoCXFPort", targetNamespace = "http://test.org")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public class DemoCXF {
    @WebMethod()
    @WebResult(targetNamespace = "http://test.org", name = "updatedEmployee")
    public Employee processEmployeeSalary(
        @WebParam(partName = "employee", name = "employee", targetNamespace = "http://test.org") 
        Employee emp,
        @WebParam(partName = "incrementAmount", name = "incrementAmount", targetNamespace = "http://test.org")
        Long incrementAmount) {
        Map<String,Object> inProps= new HashMap<String,Object>();
        inProps.put(WSHandlerConstants.ACTION, "Signature");
        inProps.put(WSHandlerConstants.SIG_PROP_FILE, "server.properties");
        EndpointImpl jaxWsEndpoint = (EndpointImpl) EndpointImpl.publish(WSDL_URL, new DemoCXF());
        Endpoint cxfEndpoint = jaxWsEndpoint.getServer().getEndpoint();
        WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps);
        cxfEndpoint.getInInterceptors().add(wssIn);
        System.out.println("[DemoCXF] Method Invoked....processEmployeeSalary");
        System.out.println("[DemoCXF] Before processing: " + emp);
        long incrementedSalary = emp.getEmpSalary() + incrementAmount;
        emp.setEmpSalary(incrementedSalary);
        System.out.println("[DemoCXF] After processing: " + emp);
        return emp;
    }
}

WS可以使用URL: cxfpoc?wsdl

现在对于客户部分,我使用下面的属性文件和privatestore.jks

client_sign.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=testUser
org.apache.ws.security.crypto.merlin.keystore.file=privatestore.jks

我已经把下面JAR的类路径为客户端:-

commons-logging-1.1.1.jar
DemoCXFClient.jar [ Generated Client ] 
neethi-3.0.1.jar
wsdl4j-1.6.2.jar
wss4j-1.6.5.jar
xmlschema-core-2.0.jar
xmlsec-1.5.1.jar
and CFX jars from jboss-as-7.1.1.Finalmodulesorgapachecxfmain folder
客户机代码

TestCXF.java

import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.handler.WSHandlerConstants;
import client.DemoCXF;
import client.DemoCXFService;
import client.Employee;
public class TestCXF {
    public static void main(String ar[]) throws Exception {
        String WSDL_URL= arr[0] + "/cxfpoc?wsdl";
        DemoCXFService service=new DemoCXFService(new URL(WSDL_URL));
        DemoCXF port=service.getDemoCXFPort();
        Client client = ClientProxy.getClient(port);
        client.getInInterceptors().add(new LoggingInInterceptor());
        client.getOutInterceptors().add(new LoggingOutInterceptor());
        Map<String,Object> outProps = new HashMap<String,Object>();
        outProps.put(WSHandlerConstants.MUST_UNDERSTAND, "0");
        outProps.put(WSHandlerConstants.ACTION, "Signature");
        outProps.put(WSHandlerConstants.USER, "testUser");
        outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, KeystorePasswordCallback.class.getName());
        outProps.put(WSHandlerConstants.SIG_PROP_FILE, "client_sign.properties");
        WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
        org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint();
        cxfEndpoint.getOutInterceptors().add(wssOut);
        Employee emp=new Employee();
        emp.setEmpNo(1000L);
        emp.setEmpName("MiddlewaremagicEmployee");
        emp.setEmpSalary(6000L);
        System.out.println("nnBefore  EmpNo: "+emp.getEmpNo()+",  Name:"+emp.getEmpName()+",  Sal:"+emp.getEmpSalary());
        emp=port.processEmployeeSalary(emp,1000L);
        System.out.println("nnAfter   EmpNo: "+emp.getEmpNo()+",  Name:"+emp.getEmpName()+",  Sal:"+emp.getEmpSalary());
    }
}

KeystorePasswordCallback.java

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
public class KeystorePasswordCallback implements CallbackHandler {
    private Map<String, String> passwords = new HashMap<String, String>();
    public KeystorePasswordCallback() {
        passwords.put("testUser", "testPass");
    }
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (int i = 0; i < callbacks.length; i++) {
            WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];
            if (pc.getIdentifier().equals("testUser")) {
                // set the password on the callback. This will be compared to the
                // password which was sent from the client.
                pc.setPassword("testPass");
            }
        }
    }
    /**
     * Add an alias/password pair to the callback mechanism.
     */
    public void setAliasPassword(String alias, String password) {
        passwords.put(alias, password);
    }
}

当我运行客户端程序时,我得到以下异常:

20:11:49,296 ERROR [org.jboss.ws.common.invocation.InvocationHandlerJAXWS] (http--127.0.0.1-8080-2) Method invocation failed with exception: null: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0]
    at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0]
    at org.jboss.ws.common.invocation.AbstractInvocationHandlerJSE.invoke(AbstractInvocationHandlerJSE.java:111)
    at org.jboss.wsf.stack.cxf.JBossWSInvoker._invokeInternal(JBossWSInvoker.java:181)
    at org.jboss.wsf.stack.cxf.JBossWSInvoker.invoke(JBossWSInvoker.java:127)
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [rt.jar:1.7.0]
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) [rt.jar:1.7.0]
    at java.util.concurrent.FutureTask.run(FutureTask.java:166) [rt.jar:1.7.0]
    at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:106)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:207)
    at org.jboss.wsf.stack.cxf.RequestHandlerImpl.handleHttpRequest(RequestHandlerImpl.java:91)
    at org.jboss.wsf.stack.cxf.transport.ServletHelper.callRequestHandler(ServletHelper.java:169)
    at org.jboss.wsf.stack.cxf.CXFServletExt.invoke(CXFServletExt.java:87)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:185)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:108)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
    at org.jboss.wsf.stack.cxf.CXFServletExt.service(CXFServletExt.java:135)
    at org.jboss.wsf.spi.deployment.WSFServlet.service(WSFServlet.java:140) [jbossws-spi-2.0.3.GA.jar:2.0.3.GA]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:]
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:]
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:]
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
    at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0]
Caused by: java.lang.NoClassDefFoundError: org/apache/cxf/jaxws/EndpointImpl
    at ws.DemoCXF.processEmployeeSalary(DemoCXF.java:37) [classes:]
    ... 38 more
Caused by: java.lang.ClassNotFoundException: org.apache.cxf.jaxws.EndpointImpl from [Module "deployment.cxfpoc.war:main" from Service Module Loader]
    at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190)
    at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:468)
    at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:456)
    at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398)
    at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:120)
    ... 39 more
20:11:49,359 WARNING [org.apache.cxf.phase.PhaseInterceptorChain] (http--127.0.0.1-8080-2) Application {http://test.org}DemoCXFService#{http://test.org}processEmployeeSalary has thrown exception, unwinding now: org.apache.cxf.interceptor.Fault: org/apache/cxf/jaxws/EndpointImpl
    at org.jboss.wsf.stack.cxf.JBossWSInvoker.createFault(JBossWSInvoker.java:246)
    at org.jboss.wsf.stack.cxf.JBossWSInvoker._invokeInternal(JBossWSInvoker.java:201)
    at org.jboss.wsf.stack.cxf.JBossWSInvoker.invoke(JBossWSInvoker.java:127)
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [rt.jar:1.7.0]
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) [rt.jar:1.7.0]
    at java.util.concurrent.FutureTask.run(FutureTask.java:166) [rt.jar:1.7.0]
    at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:106)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:207)
    at org.jboss.wsf.stack.cxf.RequestHandlerImpl.handleHttpRequest(RequestHandlerImpl.java:91)
    at org.jboss.wsf.stack.cxf.transport.ServletHelper.callRequestHandler(ServletHelper.java:169)
    at org.jboss.wsf.stack.cxf.CXFServletExt.invoke(CXFServletExt.java:87)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:185)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:108)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
    at org.jboss.wsf.stack.cxf.CXFServletExt.service(CXFServletExt.java:135)
    at org.jboss.wsf.spi.deployment.WSFServlet.service(WSFServlet.java:140) [jbossws-spi-2.0.3.GA.jar:2.0.3.GA]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]

感谢建议我如何解决这个问题,我被困在这个3天。如有任何帮助,不胜感激。

—2013年5月5日-使用下面的代码为服务器工作良好,WS被调用没有任何错误,但拦截器不工作,在这种情况下,意味着没有安全性验证让我知道我该如何解决这个问题?

package ws;

import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
import org.apache.ws.security.handler.WSHandlerConstants;
@WebService(name = "DemoCXF", serviceName = "DemoCXFService", portName = "DemoCXFPort", targetNamespace = "http://test.org")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public class DemoCXF  implements DemoCXFI{
@WebMethod()
@WebResult(targetNamespace = "http://test.org", name = "updatedEmployee")
public Employee processEmployeeSalary(
        @WebParam(partName = "employee", name = "employee", targetNamespace = "http://test.org") Employee emp,
        @WebParam(partName = "incrementAmount", name = "incrementAmount", targetNamespace = "http://test.org") Long incrementAmount) {
    Map<String, Object> inProps = new HashMap<String, Object>();
    inProps.put(WSHandlerConstants.ACTION, "Signature");
    inProps.put(WSHandlerConstants.SIG_PROP_FILE, "server.properties");
    inProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, KeystorePasswordCallback.class.getName());
    WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps);

    System.out.println("[DemoCXF] Method STEP1");
    // Endpoint cxfEndpoint = null;
    try {

        //EndpointImpl jaxWsEndpoint = (EndpointImpl)
            //    EndpointImpl.publish("http://localhost:8080/cxfpoc?wsdl",DemoCXFI.class);
        Service cxfService = Service.create(new URL(
                "http://localhost:8080/cxfpoc?wsdl"), new QName(
                        "http://test.org", "DemoCXFService"));
        DemoCXFI mySer = cxfService.getPort(DemoCXFI.class); 
        Client client = ClientProxy.getClient(mySer); 
        client.getInInterceptors().add(new LoggingInInterceptor());
        client.getOutInterceptors().add(new LoggingOutInterceptor());

        Endpoint cxfEndpoint = client.getEndpoint();
        System.out.println("[DemoCXF] Method STEP2");
    //   Endpoint cxfEndpoint = jaxWsEndpoint.getServer().getEndpoint();
        System.out.println("[DemoCXF] Method STEP3");

        System.out.println("[DemoCXF] Method STEP4");
        cxfEndpoint.getInInterceptors().add(wssIn);
        cxfEndpoint.getInInterceptors().add(new LoggingInInterceptor());
        cxfEndpoint.getOutInterceptors().add(new LoggingOutInterceptor());

        System.out
        .println("[DemoCXF] Method Invoked....processEmployeeSalary");
        System.out.println("[DemoCXF] Before processing: " + emp);
        long incrementedSalary = emp.getEmpSalary() + incrementAmount;
        emp.setEmpSalary(incrementedSalary);
        System.out.println("[DemoCXF] After processing: " + emp);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    // Below line is having error//
    /*
     * EndpointImpl jaxWsEndpoint = (EndpointImpl)
     * EndpointImpl.publish("http://localhost:8085/cxfpoc", new DemoCXF());
     */
    // Some Business Logic to Store the Employee's Updated Details in
    // Database or Messaging System.
    return emp;
}

}

请参考JBoss AS 7/WildFly 8之上运行基于Apache CXF端点的jbosssws文档:https://docs.jboss.org/author/display/JBWS/WS-Security。为了更好地理解Apache CXF在JBoss上的集成,还可以查看文档的其余部分。

最新更新