spring集成cxf 带密码验证

cxf版本 3.2.5
spring集成cxf所需jar包下载
cxf 3.2.5版本需要spring-beans-4.2.9.RELEASE.jar

服务端

接口声明

import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;

@WebService
@SOAPBinding(style = Style.RPC)
public interface PlanService {

    public String sendData(String xmlStr, String type);

}

密码回调

import java.io.IOException;
import java.util.ResourceBundle;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.wss4j.common.ext.WSPasswordCallback;


public class CallbackService implements CallbackHandler {

    private static final String BUNDLE_LOCATION = "org.xx.xx.xx.config.pass";  
    private static final String PASSWORD_PROPERTY_NAME = "auth.manager.password";  

    private static String password;  
    static {  
        final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_LOCATION);  
        password = bundle.getString(PASSWORD_PROPERTY_NAME);  
    }  

    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("usertest")){
                pc.setPassword(password);
                return;
            }
        }  

    }

}

cxf配置文件

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


    <!-- 服务端 -->
    <beans:import resource="classpath:META-INF/cxf/cxf.xml" />

    <beans:bean id="WSS4JInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">  
        <beans:constructor-arg>  
            <beans:map>  
                <beans:entry key="action" value="UsernameToken" />  
                <beans:entry key="passwordType" value="PasswordText" />  
                <beans:entry key="user" value="usertest" />
                <beans:entry key="passwordCallbackClass"  
                    value="org.xx.xx.webservice.service.service.CallbackService" />  
            </beans:map>  
        </beans:constructor-arg>  
    </beans:bean>
    <!-- <beans:bean id="WSS4JOutInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">  
        <beans:constructor-arg>  
            <beans:map>  
                <beans:entry key="action" value="UsernameToken" />  
                <beans:entry key="passwordType" value="PasswordText" />  
                <beans:entry key="passwordCallbackClass"  
                    value="org.xx.xx.webservice.service.service.CallbackService" />  
            </beans:map>  
        </beans:constructor-arg>  
    </beans:bean>   -->

    <beans:bean id="dataHandlerService" class="org.xx.xx.webservice.service.service.DataHandlerService"/>
    <beans:bean id="PlanServiceImpl" class="org.xx.xx.webservice.service.impl.PlanServiceImpl">
        <beans:property name="dataHandlerService" ref="dataHandlerService"></beans:property>
    </beans:bean>
    <jaxws:endpoint id="PlanData" implementor="org.herysoft.expertsys.webservice.service.impl.PlanServiceImpl" address="/sendData" >
        <jaxws:features>
            <beans:bean class="org.apache.cxf.feature.LoggingFeature"/>
        </jaxws:features>
        <jaxws:inInterceptors>
            <beans:ref bean="WSS4JInInterceptor" />
            <!-- <beans:ref bean="WSS4JOutInterceptor" /> -->
        </jaxws:inInterceptors>
    </jaxws:endpoint>

</beans:beans>

在web.xml里加上:

<servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/webService/*</url-pattern>
</servlet-mapping>

客户端

调用方式一
首先生成接口代码,用

//-s 生成在指定目录下
//java自带wsdl转换工具
wsimport -s d:\src http://localhost:8080/myProject/webService/sendData?wsdl

或者

//-s 生成在指定目录下
//java自带wsdl转换工具
wsdl2java -s d:\src http://localhost:8080/myProject/webService/sendData?wsdl

这里写图片描述
注意服务端配置了WSS4JInInterceptor,客户端要配上相应WSS4JOutInterceptor

        Map<String, Object> outProps = new HashMap<>();
        outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
        outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
        outProps.put(WSHandlerConstants.USER, "usertest");
        outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, "org.xx.xx.webservice.util.PasswordCallback");

        PlanServiceImplService service = new PlanServiceImplService();
        PlanService port = service.getPlanServiceImplPort();
        org.apache.cxf.endpoint.Client client = ClientProxy.getClient(port);
        client.getOutInterceptors().add(new WSS4JOutInterceptor(outProps));

        port.sendData("<data>abc</data>","1");

密码回调类

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.wss4j.common.ext.WSPasswordCallback;


public class PasswordCallback implements CallbackHandler {

    private Map<String, String> passwords = new HashMap<>();

    public PasswordCallback() {
        passwords.put("usertest", "pass123");
    }

    /**
     * Here, we attempt to get the password from the private
     * alias/passwords map.
     */
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (int i = 0; i < callbacks.length; i++) {
            WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];

            String pass = passwords.get(pc.getIdentifier());
            if (pass != null) {
                pc.setPassword(pass);
                return;
            }
        }
    }

    /**
     * Add an alias/password pair to the callback mechanism.
     */
    public void setAliasPassword(String alias, String password) {
        passwords.put(alias, password);
    }

}

调用方式二
soap ui工具调用wsdl,这里是发送报文格式
访问以下链接生成报文

http://localhost:8080/myProject/webService/sendData?wsdl
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.webservice.expertsys.herysoft.org/">
<soapenv:Header>
   <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    <wsse:UsernameToken wsu:Id="UsernameToken-27777511" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <wsse:Username>usertest</wsse:Username>
    <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">xxxxxx</wsse:Password>
    </wsse:UsernameToken>
   </wsse:Security>
</soapenv:Header>

   <soapenv:Body>
      <ser:sendData>
         <arg0>?</arg0>
         <arg1>?</arg1>
      </ser:sendData>
   </soapenv:Body>
</soapenv:Envelope>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值