< 本文建立在上篇文章基础之上 >
编写服务器端用户验证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这是实现了用户的验证