Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用WSS4J(SOAP)在CXF Web服务中实现身份验证_Java_Web Services_Soap_Cxf - Fatal编程技术网

Java 使用WSS4J(SOAP)在CXF Web服务中实现身份验证

Java 使用WSS4J(SOAP)在CXF Web服务中实现身份验证,java,web-services,soap,cxf,Java,Web Services,Soap,Cxf,我正在尝试在我的Web服务中使用用户名/密码实现身份验证。目前,我学习了CXF和如何配置东西,但就我的一生而言,我就是不能把我的头绕在安全部分上 我使用CXF从WSDL创建Java类。这是我对Web服务的XML配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns

我正在尝试在我的Web服务中使用用户名/密码实现身份验证。目前,我学习了CXF和如何配置东西,但就我的一生而言,我就是不能把我的头绕在安全部分上

我使用CXF从WSDL创建Java类。这是我对Web服务的XML配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

<jaxws:endpoint id="pacService" implementor="com.logicalprovisioning.internal.PacWS" address="/PacRequestSoapHttpPort">
    <jaxws:properties>
        <entry key="exceptionMessageCauseEnabled" value="true" />
        <entry key="security.callback-handler" value="com.logicalprovisioning.webservices.clients.autheticate.AuthenticationCallback"/>
    </jaxws:properties>
</jaxws:endpoint>
</beans>
目前这是一份草稿

我编写了一个客户端,用于初始化WebService(一个抽象类),并继承它以在不同的WebService中使用

public abstract class WebServiceClientBase implements HandlerResolver, SOAPHandler<SOAPMessageContext> {

    protected int connectTimeout;

    protected String endPointUrl;
    protected String password;
    protected String userName;

    protected Logger logger = null;

    private Service service = null;


    public WebServiceClientBase () {
        super();
    }

    public void init() {

        // Set the security handler
        getService().setHandlerResolver(new HandlerResolverImpl());

        // Setting endpoint URL and timeout...
        getBindingProvider().getRequestContext().put("javax.xml.ws.client.receiveTimeout", connectTimeout);
        getBindingProvider().getRequestContext().put("javax.xml.ws.client.connectionTimeout", connectTimeout);
        getBindingProvider().getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endPointUrl);


        Map<String, List<String>> headers = new HashMap<String, List<String>>();

        headers.put("Content-Type", Collections.singletonList("application/soap+xml"));
        headers.put(Message.ENCODING, Collections.singletonList("UTF-8"));

        getBindingProvider().getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, headers);
    }

    @Override
    @SuppressWarnings("rawtypes")
    public List<Handler> getHandlerChain(PortInfo arg0) {

        List<Handler> handlerChain = new ArrayList<Handler>();

        handlerChain.add(this);

        return handlerChain;
    }

    @Override
    public boolean handleMessage(SOAPMessageContext soapMessageContext) {

        if (!((Boolean) soapMessageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)). booleanValue()) {
            return true;
        }

        return true;
    }
    
    @Override
    public boolean handleFault(SOAPMessageContext arg0) {
        return false;
    }

    @Override
    public void close(MessageContext arg0) {

    }

    @Override
    public Set<QName> getHeaders() {
        return null;
    }

    protected Service getService() {
        return service;
    }

    protected void setService(Service service) {
        this.service = service;
    }

    protected abstract BindingProvider getBindingProvider();
}
公共抽象类WebServiceClientBase实现HandlerResolver、SOAPHandler{
受保护的int连接超时;
受保护的字符串端点URL;
受保护的字符串密码;
受保护的字符串用户名;
受保护的记录器=null;
私有服务=null;
公共WebServiceClient数据库(){
超级();
}
公共void init(){
//设置安全处理程序
getService().setHandlerResolver(新的HandlerResolverImpl());
//正在设置终结点URL和超时。。。
getBindingProvider().getRequestContext().put(“javax.xml.ws.client.receiveTimeout”,connectTimeout);
getBindingProvider().getRequestContext().put(“javax.xml.ws.client.connectionTimeout”,connectTimeout);
getBindingProvider().getRequestContext().put(BindingProvider.ENDPOINT\u ADDRESS\u属性,endPointUrl);
Map headers=newhashmap();
headers.put(“内容类型”,Collections.singletonList(“应用程序/soap+xml”);
headers.put(Message.ENCODING、Collections.singletonList(“UTF-8”));
getBindingProvider().getRequestContext().put(MessageContext.HTTP_请求_头,头);
}
@凌驾
@抑制警告(“原始类型”)
公共列表getHandlerChain(PortInfo arg0){
List handlerChain=new ArrayList();
handlerChain.add(这个);
返回手柄链;
}
@凌驾
公共布尔handleMessage(SOAPMessageContext SOAPMessageContext){
if(!((布尔)soapMessageContext.get(MessageContext.MESSAGE_OUTBOUND_属性)).booleanValue(){
返回true;
}
返回true;
}
@凌驾
公共布尔handleFault(SOAPMessageContext arg0){
返回false;
}
@凌驾
公共作废关闭(MessageContext arg0){
}
@凌驾
公共集getHeaders(){
返回null;
}
受保护的服务getService(){
回程服务;
}
受保护的无效设置服务(服务服务){
服务=服务;
}
受保护的抽象BindingProvider getBindingProvider();
}
我已经走了这么远了。我不确定如何将身份验证信息与webservice调用连接起来


任何指示都会有帮助。我一开始也在正确的轨道上吗?通过浏览所有教程和示例,我可能会陷入死胡同。

假设com.logicalprovisioning.internal.PacWS是jaxws生成的PortType类,您可以这样做

...
com.logicalprovisioning.internal.PacWS pacWsPort = getService().get...Port();
org.apache.cxf.endpoint.Client client = org.apache.cxf.frontend.ClientProxy.getClient(pacWSPort);
org.apache.cxf.endpoint.Endpoint endpoint = client.getEndpoint();

Map<String, Object> props = new HashMap<>();
props.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
props.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
props.put(WSHandlerConstants.PW_CALLBACK_CLASS, AuthenticationCallback.class.getName());
props.put(WSHandlerConstants.USER, "TIM");
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(props);
endpoint.getOutInterceptors().add(wssOut);

// you can then call @WebMethod annotated methods on your PacWS object, and it should populate the wss-security soap header
。。。
com.logicalprovisioning.internal.PacWS pacWsPort=getService().get…Port();
org.apache.cxf.endpoint.Client Client=org.apache.cxf.frontend.ClientProxy.getClient(pacWSPort);
org.apache.cxf.endpoint.endpoint=client.getEndpoint();
Map props=newhashmap();
put(WSHandlerConstants.ACTION、WSHandlerConstants.USERNAME\u令牌);
put(WSHandlerConstants.PASSWORD\u类型,WSConstants.PW\u文本);
put(WSHandlerConstants.PW_CALLBACK_类,AuthenticationCallback.CLASS.getName());
props.put(wshandlerstants.USER,“TIM”);
WSS4JOutInterceptor wssOut=新WSS4JOutInterceptor(道具);
getOutiterCeptors().add(wssOut);
//然后可以在PacWS对象上调用@WebMethod注释的方法,它应该填充wss安全soap头

上面的一些代码可能可以替换为cxf xml配置文件中的配置

我不确定如何将身份验证信息与Web服务调用连接起来
您是在谈论基本身份验证还是与WS-Security相关的身份验证?WS-Security是我正在研究的。我读了这本指南,并查阅了其中的一些例子。但我还是没能下定决心。就我理解你的问题而言,你正在寻找一种方法将身份验证信息添加到你的客户端请求中?您可以尝试定义
ws-security
属性和客户端回调处理程序,或者使用引用回调处理程序的
WSS4JOutInterceptor
,如博客链接所示。我要试一试。我会回来的我会找到一些我不知道的东西understand@RomanVottner这两个链接很有帮助。我比以前走得更远了一点。但我一直停留在如何在由CXF wsdl2java创建的客户机上添加令牌/密码信息的方面。我发现的大多数示例都是从头开始编写的。
...
com.logicalprovisioning.internal.PacWS pacWsPort = getService().get...Port();
org.apache.cxf.endpoint.Client client = org.apache.cxf.frontend.ClientProxy.getClient(pacWSPort);
org.apache.cxf.endpoint.Endpoint endpoint = client.getEndpoint();

Map<String, Object> props = new HashMap<>();
props.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
props.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
props.put(WSHandlerConstants.PW_CALLBACK_CLASS, AuthenticationCallback.class.getName());
props.put(WSHandlerConstants.USER, "TIM");
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(props);
endpoint.getOutInterceptors().add(wssOut);

// you can then call @WebMethod annotated methods on your PacWS object, and it should populate the wss-security soap header