我正在尝试使用CXF 3.1.0和Spring 4.1.6在我的服务中实现WS-Policy
我发现的大多数示例都是使用CXF 2,并且在CXF新版本中更改了cxf-extension-policy.xml和cxf-extension-ws-security.xml等结构。
我尝试过类似的事情:
package spring;
import java.util.LinkedList;
import java.util.List;
import javax.xml.ws.Endpoint;
import org.apache.cxf.Bus;
import org.apache.cxf.feature.AbstractFeature;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.ws.policy.WSPolicyFeature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import com.student.StudentService;
import com.student.service.StudentServiceImpl;
@Configuration
@ImportResource({"classpath:META-INF/cxf/cxf.xml"})
public class CXFConfig {
@Autowired
private Bus cxfBus;
@Bean
public StudentService service(){
return new StudentServiceImpl();
}
@Autowired
@Bean
public Endpoint serviceImpl(
final StudentService service){
EndpointImpl endpoint = new EndpointImpl(this.cxfBus, service);
endpoint.setAddress("/StudentService");
endpoint.publish();
return endpoint;
}
}
我的WSDL有一些策略,基本上是来自this tutorial
的WSDL我使用Contract-first生成我的Java类。
当我运行项目时,我的政策不会出现。
我试过
final Map<String, Object> properties = new HashMap<>();
properties.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
properties.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
properties.put(WSHandlerConstants.PW_CALLBACK_REF, ServerPasswordCallback.class.getName());
EndpointImpl endpoint = new EndpointImpl(this.cxfBus, portType);
endpoint.setProperties(properties);
endpoint.setAddress("/StudentService");
endpoint.publish();
return endpoint;
我也试过
final Map<String, Object> properties = new HashMap<>();
properties.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
properties.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
properties.put(WSHandlerConstants.PW_CALLBACK_REF, ServerPasswordCallback.class.getName());
cxfBus.getFeatures().add(new WSPolicyFeature());
cxfBus.getInInterceptors().add(new WSS4JInInterceptor(properties));
EndpointImpl endpoint = new EndpointImpl(this.cxfBus, portType);
endpoint.setAddress("/StudentService");
endpoint.publish();
return endpoint;
和
WSPolicyFeature wsPolicyFeature = new WSPolicyFeature();
wsPolicyFeature.initialize(this.cxfBus);
这些都不起作用。
有人知道如何使用Spring注释配置它吗?
答案 0 :(得分:2)
过了一会儿,我发现WSS4J使用拦截器的概念而不是合同中的策略。
我将我的spring实现改为
EndpointImpl endpoint = new EndpointImpl(this.cxfBus, flightService);
endpoint.setAddress("/FlightService");
endpoint.setWsdlLocation("src/main/resources/wsdls/flightservice_v1r1.wsdl");
endpoint.getProperties().put("ws-security.callback-handler", new ServerPasswordCallback());
endpoint.publish();
然而,即使我在部署合同时使用了该配置,它也显示了2个wsdl:binding和2个wsdl:service ...
我找到了解决问题的方法,而不是第一种解决方案,我将我的政策外部化为XML文件并使用
来激活我的服务@Policies({
@Policy(uri="classpath:policies/usernameToken.xml", includeInWSDL=true)
})
我的Spring配置已缩减为
EndpointImpl endpoint = new EndpointImpl(this.cxfBus, new FlightServiceImpl());
endpoint.setAddress("/FlightService");
endpoint.getProperties().put("ws-security.callback-handler", new ServerPasswordCallback());
endpoint.publish();
当我部署项目时,我终于看到了
<wsdl:service name="FlightServiceImplService">
<wsdl:port binding="tns:FlightServiceImplServiceSoapBinding" name="FlightServiceImplPort">
<soap:address location="http://localhost:8080/ws-security/FlightService"/>
</wsdl:port>
<wsp:PolicyReference URI="#authenticationPolicy"/>
</wsdl:service>
答案 1 :(得分:0)
好吧,我的问题不是在CXF / Spring配置中...在WSDL中我是在depoy时预期的。
我期待这样的事情:
<wsdl:binding name="ChangeStudentDetailsImplServiceSoapBinding" type="tns:ChangeStudentDetails">
<wsp:PolicyReference URI="#ChangeStudentDetailsImplServiceSoapBindingPolicy"/>
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="changeName">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="changeName">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="changeNameResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ChangeStudentDetailsImplService">
<wsdl:port binding="tns:ChangeStudentDetailsImplServiceSoapBinding" name="ChangeStudentDetailsImplPort">
<wsp:PolicyReference URI="#ChangeStudentDetailsImplServiceSoapBindingPolicy"/>
<soap:address location="http://localhost:8080/ws-policy/ChangeStudent"/>
</wsdl:port>
</wsdl:service>
然而,当我使用契约优先方法时,我收到了:
<wsdl:binding name="ChangeStudentDetailsImplServiceSoapBinding" type="tns:ChangeStudentDetails">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="changeName">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="changeName">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="changeNameResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ChangeStudentDetailsImplService">
<wsdl:port binding="tns:ChangeStudentDetailsImplServiceSoapBinding" name="ChangeStudentDetailsImplPort">
<soap:address location="http://localhost:8080/ws-policy/ChangeStudent"/>
</wsdl:port>
</wsdl:service>
所以我觉得那不行。
我将CXF / Spring配置更改为
@Autowired
@Bean
public Endpoint serviceImpl(
final ChangeStudentDetails portType){
Map<String, Object> inProps = new HashMap<String, Object>();
inProps.put("action", "UsernameToken");
inProps.put("passwordType", "PasswordText");
inProps.put("passwordCallbackClass", ServerPasswordCallback.class.getName());
EndpointImpl endpoint = new EndpointImpl(this.cxfBus, portType);
endpoint.getInInterceptors().add(new WSS4JInInterceptor(inProps));
endpoint.setAddress("/StudentService");
endpoint.publish();
return endpoint;
}
当我通过SOAPUI执行此操作时,我设置了身份验证的类型,用户名和密码并且正常工作。我只是不明白为什么我的政策没有出现
答案 2 :(得分:0)
我会尝试这样的东西加载外部政策:
{ %load static %}