`
阅读更多
CXF的webService已经创建好,但没有安全可言,毕竟这是Internet服务呀。
CXF给了一个很完整的安全架构,但CXF给出的ws_security DEMO太复杂了,又是password jks X509 Timestamp。 我试了很多次都没有成功。化繁为简,只实现一个user password好了。下面开始
编写cxf.xml在原来的bean的地方声明一下就可以了

Java代码

<bean id="WSS4JInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"> 

            <constructor-arg> 

                <map> 

                    <entry key="action" value="UsernameToken" /> 

                    <entry key="passwordType" value="PasswordText" /> 

                    <entry key="passwordCallbackClass"

                        value="com.xxxx.Service.ServerPasswordCallback" /> 

                </map> 

        </constructor-arg> 

    </bean> 

    <jaxws:endpoint id="chartScreen" implementor="#chartScreenService"

    address="/ChartScreenService" >

  

  

        <jaxws:inInterceptors>

<bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" /> 

                 <ref bean="WSS4JInInterceptor" /> 

            </jaxws:inInterceptors> 

      

    </jaxws:endpoint>

                <bean id="WSS4JInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">

   <constructor-arg>

     <map>

      <entry key="action" value="UsernameToken" />

      <entry key="passwordType" value="PasswordText" />

      <entry key="passwordCallbackClass"

        value="com.mms.webservice.test.ServerPasswordCallback" />

     </map>

   </constructor-arg>

  </bean>



<jaxws:endpoint id="helloWorld"

   implementor="com.mms.webservice.HelloWorldImpl"

   address="/HelloWorld">

   <jaxws:inInterceptors>

   <!--

     <bean

      class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />

     <bean

      class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">

      <constructor-arg>

        <map>

         <entry key="action" value="UsernameToken" />

         <entry key="passwordType" value="PasswordText" />

         <entry key="passwordCallbackClass"

           value="com.mms.webservice.test.ServerPasswordCallback" />

        </map>

      </constructor-arg>

     </bean>

      -->

      <ref bean="WSS4JInInterceptor" />

   </jaxws:inInterceptors>

  </jaxws:endpoint>


WSS4JInInterceptor就是我们要定义的东东了。CXf已经帮你写好了。设置属性就可以了。里面属性值挺多的,CXF的文档就是太简单了,opensource的弊病!属性值就查API吧。
下面需要写server端的密码回调函数,验证logic就在这里定义了。

Java代码



public class ServerPasswordCallback implements CallbackHandler {

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

    public ServerPasswordCallback(){

    passwords.put("admin", "admin");

    passwords.put("test", "test");

    }

    @Override

    public void handle(Callback[] callbacks) throws IOException,

            UnsupportedCallbackException {

    for (int i = 0; i < callbacks.length; i++) {

        WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

        if(!passwords.containsKey(pc.getIdentifier()))

        throw new WSSecurityException("user not match");

        String pass = passwords.get(pc.getIdentifier());

        String pwd = pc.getPassword();

        if (pwd == null || !pwd.equals(pass)){

         throw new WSSecurityException("password not match");

        }

    }

  

    }



}就此server端的验证就全部ok了。这时再调用原来的调用程序就会报ws_security错误了。

下面给出Client验证程序
其实就是在soapheader上加相应内容。也需要用到inInterceptors

Java代码

public class ClientPasswordCallback implements CallbackHandler {

    private Map<String, String> passwords =

        new HashMap<String, String>();

    public ClientPasswordCallback(){

     passwords.put("admin", "admin");

     passwords.put("test", "test");

    }

    @Override

    public void handle(Callback[] callbacks) throws IOException,

            UnsupportedCallbackException {

    for (int i = 0; i < callbacks.length; i++) {

        WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

        int usage = pc.getUsage();

        if(!passwords.containsKey(pc.getIdentifier()))

        throw new WSSecurityException("user not exists ");

        String pass = passwords.get(pc.getIdentifier());

        if (usage == WSPasswordCallback.USERNAME_TOKEN  && pass != null) {

       pc.setPassword(pass);

       return;

        }

    }

    }

}





JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();

     

       Map<String, Object> outProps = new HashMap<String, Object>();

       outProps.put(WSHandlerConstants.ACTION,

       WSHandlerConstants.USERNAME_TOKEN);

       outProps.put(WSHandlerConstants.USER, "admin");

       outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);

       outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,

       ClientPasswordCallback.class.getName());



       WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);

       factory.getOutInterceptors().add(wssOut);

       factory.getOutInterceptors().add(new SAAJOutInterceptor());



     

       factory.setServiceClass(IChartScreenService.class);

       factory.setAddress("http://localhost:8080/ECFlight/service/ChartScreenService");

       IChartScreenService service = (IChartScreenService) factory.create();



也可采用spring 配置:

  <!-- wssecurity -->
   <bean id="clientPasswordCallback" class="com.evermoresw.megp.utilities.ClientPasswordCallback" />
    <bean id="wsOutInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
        <constructor-arg>
            <map>
                <entry key="action" value="UsernameToken" />
                <entry key="passwordType" value="PasswordText" />
                <entry key="user" value="admin" />
                <entry key="passwordCallbackRef">
                    <ref bean="clientPasswordCallback" />
                </entry>
            </map>
        </constructor-arg>
    </bean>
    <jaxws:client id="client_testService" serviceClass="com.evermore.moa.service.Test"
        address="http://localhost:8080/cxfTestServer/service/testService">
        <jaxws:outInterceptors>

<bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />

            <ref bean="wsOutInterceptor"/>
        </jaxws:outInterceptors>
    </jaxws:client>



问题:Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/xml/security/Init

加上:xmlsec-1.4.3.jar包



For WS-Security support:

- bcprov-jdk15.jar

- xalan.jar

- serializer.jar

- wss4j.jar

- xmlsec.jar
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics