< 本文建立在上篇文章基础之上 >
编写服务器端用户验证WsAuthHandler.java类
package Interceptor; import java.io.IOException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import org.apache.ws.security.WSPasswordCallback; public class WsAuthHandler implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ COME IN @@@@@@@@@@@@@@"); for (int i = 0; i < callbacks.length; i++) { WSPasswordCallback pc = (WSPasswordCallback) callbacks[i]; String identifier = pc.getIdentifier(); int usage = pc.getUsage(); if (usage == WSPasswordCallback.USERNAME_TOKEN) { pc.setPassword("testPassword"); } else if (usage == WSPasswordCallback.SIGNATURE) { pc.setPassword("testPassword"); } } } }
进行发布服务
<jaxws:server id="userService" serviceClass="com.IComplexUserService" address="/userService"> <!-- 指向实现类 --> <jaxws:serviceBean> <ref bean="userServiceBean" /> </jaxws:serviceBean> <!--进入web service之前用户验证的拦截器--> <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="action" value="UsernameToken Timestamp" /> 设置密码类型为加密<entry key="passwordType" value="PasswordDigest" /> --> <entry key="passwordCallbackClass" value="Interceptor.WsAuthHandler" /> </map> </constructor-arg> </bean> </jaxws:inInterceptors> </jaxws:server>
客户端编写WsClinetAuthHandler.java类记性验证
package com.client; import java.io.IOException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import org.apache.ws.security.WSPasswordCallback; public class WsClinetAuthHandler implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { WSPasswordCallback pc = (WSPasswordCallback) callbacks[i]; System.out.println("identifier: " + pc.getIdentifier()); // 这里必须设置密码,否则会抛出:java.lang.IllegalArgumentException: pwd == null // but a password is needed pc.setPassword("testPassword");//这里必须设置密码 } } }
调用服务
package com.client; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.cxf.binding.soap.interceptor.SoapInterceptor; import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor; import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; import org.apache.ws.security.WSConstants; import org.apache.ws.security.handler.WSHandlerConstants; public class UserAccess { public List UserAccess(String username, String password) { // 以下和服务端配置类似,不对,应该说服务端和这里的安全验证配置一致 Map<String, Object> outProps = new HashMap<String, Object>(); outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN); outProps.put(WSHandlerConstants.USER, username); outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT); // 指定在调用远程ws之前触发的回调函数WsClinetAuthHandler,其实类似于一个拦截器 outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, WsClinetAuthHandler.class.getName()); ArrayList<SoapInterceptor> list = new ArrayList<SoapInterceptor>(); // 添加cxf安全验证拦截器,必须 list.add(new SAAJOutInterceptor()); list.add(new WSS4JOutInterceptor(outProps)); return list; } }
OK这是实现了用户的验证