下面看一下Axis中如何使用用户名、口令来控制对WebService 的访问。
在myservices/WEB-INF下创建一个名为users.lst的文本文件,一行表示一对用户名、口令,之间用空格分隔,内容如下:
user1 password1
user2 password2
实现一个WebService,它有一个foo()方法,该方法打印出通过身份认证的用户的用户名,代码如下:
SecurityService.java
package chen.axisguide.ch6;
import org.apache.axis.MessageContext;
public class SecurityService {
public void foo() {
MessageContext msgContext = MessageContext.getCurrentContext();
System.out.println("你已通过身份认证!");
System.out.println("你的用户名: " + msgContext.getUsername());
}
}
为了让 Axis知晓要对该服务的访问验证用户名和口令,需要在wsdd文件中增加一个Axis自带的处理器SimpleAuthenticationHandler,该处理器会从MessageContext中取出用户名和口令,并与users.lst中的用户名和口令进行比对,如果匹配,则通过验证,继续后面的处理,否则抛出(401)Unauthorized异常。
deploy.wsdd
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
客户端在访问WebService时,需要在 Call对象中设置在users.lst文件中已有的用户名和对应的口令。客户端代码如下:
package chen.axisguide.ch6;
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;
import org.apache.axis.AxisFault;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
/**
* 访问SecurityService的客户端
*
*
*/
public class Client {
/**
* @param args
* @throws ServiceException
* @throws RemoteException
*/
public static void main(String[] args) throws ServiceException, RemoteException {
// wsdl中address 节点的location属性
String endpoint = "http://localhost:8080/myservices/services/SecurityService";
// 要调用的方法名
String method = "foo";
Service service = new Service();
Call call = (Call) service.createCall();
// 设置客户端访问的远程端点
call.setTargetEndpointAddress(endpoint);
// 设置用户名和口令
call.setUsername("user1");
call.setPassword("password1");
// 调用远程方法
try{
call.invoke(method,new Object[]{});
}catch(AxisFault e) {
System.err.println(e.getFaultString());
}
}
}
Call对象用setUserName()和setPassword()来设置用户名和口令。
Axis自带的身份认证功能比较简单,如果其安全性不能满足应用系统的要求,可以自定义一个处理器替代SimpleAuthenticationHandler,在自定义处理器中采用其他的安全框架(如Acegi http://www.acegisecurity.org/)来保护你的WebService。