CXF 安全认证

CXFwebService已经创建好,但没有安全可言,毕竟这是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

你可能感兴趣的:(bean,String,Class,action,callback,passwords)