1

我已经使用 JBOSS 在 CXF 中创建了一个 WS,我的要求是我想启用 X509 证书并使用 CXF 客户端调用 WS。我能够创建 WS 并能够成功地使用客户端调用它,但是当我实现 X509 时出现错误:-“原因:来自 [模块”部署的 java.lang.ClassNotFoundException:org.apache.cxf.jaxws.EndpointImpl。 cxfpoc.war:main" from Service Module Loader]" ,下面是相同的详细信息。

我的环境:

应用服务器:JBOSS-AS7.1.1.Final JAVA:1.7

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

1) 在密钥库中使用 testUser/testPass 生成私钥

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

2)自签名证书

keytool -selfcert -alias testUser -keystore privatestore.jks -storepass changeit -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

现在我已经复制了服务器的 WEB-INF/classes 文件夹中的 publicstore.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 服务的代码:

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

现在对于 cilent 部分,我正在使用下面的属性文件和 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

我在 Client 的类路径中放了 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.Final\modules\org\apache\cxf\main folder

客户代码

测试CXF.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("\n\nBefore  EmpNo: "+emp.getEmpNo()+",  Name:"+emp.getEmpName()+",  Sal:"+emp.getEmpSalary());
        emp=port.processEmployeeSalary(emp,1000L);
        System.out.println("\n\nAfter   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;
}

}

4

1 回答 1

0

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

于 2013-05-10T11:38:02.500 回答