1.引言
前一节介绍了使用users.lst文件来实现webservice的用户名和密码的校验,
本节介绍使用webservice的handler来实现webservice的安全校验。
这里,不用用户名和密码来实现安全校验,换一种方式,采用IP地址校验的方式。
这里通过一个配置文件来控制是否打开IP校验开关以及允许哪些IP地址的客户端可以访问。
这里的开发还是基于上一节HelloService这个基本的webservice基础上来开发。
2.项目环境
system:win7
myeclipse:6.5 tomcat:5.0 JDK:开发环境1.5,编译环境1.4
axis:1.4
服务类:
HelloServiceImpl.java
IpAuthentionHandler.java
Test1.java
前一节介绍了使用users.lst文件来实现webservice的用户名和密码的校验,
本节介绍使用webservice的handler来实现webservice的安全校验。
这里,不用用户名和密码来实现安全校验,换一种方式,采用IP地址校验的方式。
这里通过一个配置文件来控制是否打开IP校验开关以及允许哪些IP地址的客户端可以访问。
这里的开发还是基于上一节HelloService这个基本的webservice基础上来开发。
2.项目环境
system:win7
myeclipse:6.5 tomcat:5.0 JDK:开发环境1.5,编译环境1.4
axis:1.4
项目结构图如下:
3.示例代码
配置文件
web.xml---web项目的配置文件,和基本的webservice配置没任何区别
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>AxisServlet</servlet-name>
<servlet-class>
org.apache.axis.transport.http.AxisServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
server-config.wsdd---axis的配置文件,这里的配置就是一个webservice+handler的基本配置
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<globalConfiguration>
<parameter name="sendMultiRefs" value="true" />
<parameter name="disablePrettyXML" value="true" />
<parameter name="adminPassword" value="admin" />
<parameter name="attachments.Directory"
value="D:\tomcat5\webapps\WebService\WEB-INF\attachments" />
<parameter name="dotNetSoapEncFix" value="true" />
<parameter name="enableNamespacePrefixOptimization"
value="false" />
<parameter name="sendXMLDeclaration" value="true" />
<parameter name="sendXsiTypes" value="true" />
<parameter name="attachments.implementation"
value="org.apache.axis.attachments.AttachmentsImpl" />
<requestFlow>
<handler type="java:org.apache.axis.handlers.JWSHandler">
<parameter name="scope" value="session" />
</handler>
<handler type="java:org.apache.axis.handlers.JWSHandler">
<parameter name="scope" value="request" />
<parameter name="extension" value=".jwr" />
</handler>
</requestFlow>
</globalConfiguration>
<handler name="LocalResponder"
type="java:org.apache.axis.transport.local.LocalResponder" />
<handler name="URLMapper"
type="java:org.apache.axis.handlers.http.URLMapper" />
<handler name="Authenticate"
type="java:org.apache.axis.handlers.SimpleAuthenticationHandler" />
<service name="AdminService" provider="java:MSG">
<parameter name="allowedMethods" value="AdminService" />
<parameter name="enableRemoteAdmin" value="false" />
<parameter name="className" value="org.apache.axis.utils.Admin" />
<namespace>http://xml.apache.org/axis/wsdd/</namespace>
</service>
<service name="Version" provider="java:RPC">
<parameter name="allowedMethods" value="getVersion" />
<parameter name="className" value="org.apache.axis.Version" />
</service>
<transport name="http">
<requestFlow>
<handler type="URLMapper" />
<handler
type="java:org.apache.axis.handlers.http.HTTPAuthHandler" />
</requestFlow>
<parameter name="qs:list"
value="org.apache.axis.transport.http.QSListHandler" />
<parameter name="qs:wsdl"
value="org.apache.axis.transport.http.QSWSDLHandler" />
<parameter name="qs.list"
value="org.apache.axis.transport.http.QSListHandler" />
<parameter name="qs.method"
value="org.apache.axis.transport.http.QSMethodHandler" />
<parameter name="qs:method"
value="org.apache.axis.transport.http.QSMethodHandler" />
<parameter name="qs.wsdl"
value="org.apache.axis.transport.http.QSWSDLHandler" />
</transport>
<transport name="local">
<responseFlow>
<handler type="LocalResponder" />
</responseFlow>
</transport>
<!-- 配置一个handler,用来进行IP校验-->
<handler name="IPHandler" type="java:server.handler.IpAuthentionHandler">
<parameter name="status" value="success" />
</handler>
<!-- 配置自己的服务 -->
<service name="HelloService" provider="java:RPC">
<parameter name="allowedMethods" value="*" />
<parameter name="className" value="server.service.HelloServiceImpl" />
<!-- 引入IP校验的handler -->
<requestFlow>
<handler type="IPHandler" />
</requestFlow>
</service>
</deployment>
服务端文件
服务类:
HelloServiceImpl.java
package server.service;
public class HelloServiceImpl {
public String hello(String s) {
System.out.println("我是服务端......");
System.out.println("方法的入参为:"+s);
return "hello," + s;
}
}
handler处理类和配置文件:
IpAuthentionHandler.java
package server.handler;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import org.apache.axis.AxisFault;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;
import org.apache.axis.transport.http.HTTPConstants;
import org.apache.axis.utils.Messages;
//利用handler进行客户端IP校验
public class IpAuthentionHandler extends BasicHandler {
private static final long serialVersionUID = 1L;
private static Properties p = new Properties();
static {
InputStream in = null;
try {
//注意这里的文件的存放位置和文件路径的书写方式; path 不以'/'开头时默认是从此类所在的包下取资源
//这里如果我们把ip.properties放在src根目录下,然后采用src/ip.properties的形式是没法取到此文件的;
//此时需要使用 in=IpAuthentionHandler.class.getClassLoader().getResourceAsStream("ip.properties");
in = IpAuthentionHandler.class.getResourceAsStream("ip.properties");
p.load(in);
} catch (IOException e) {
System.out.println("ip.properties配置文件加载失败!");
e.printStackTrace();
} finally {
if (null != in)
try {
in.close();
} catch (IOException e) {
System.out.println("关闭流操作发生异常!");
e.printStackTrace();
}
}
}
public void invoke(MessageContext messageContext) throws AxisFault {
String status=(String)this.getOption("status");
System.out.println("IpAuthentionHandler's status is :"+status);
String uri = messageContext.getSOAPActionURI();
String targetService = messageContext.getTargetService();
System.out.println("webservice开始IP认证:service>>" + uri + "/"+ targetService);
String name = HTTPConstants.MC_HTTP_SERVLETREQUEST;
HttpServletRequest request = (HttpServletRequest) messageContext
.getProperty(name);
String remoteAddr = request.getRemoteAddr();
System.out.println("客户端IP:" + remoteAddr);
String switcher = p.getProperty("ip_switcher");
System.out.println("IP校验开关:" + switcher);
if ("on".equalsIgnoreCase(switcher)) {
System.out.println("服务端IP校验开关处于【打开】状态,需要校验IP");
String regx = p.getProperty("ip_allow");
System.out.println("允许调用服务的IP地址有:" + regx);
if (null != regx && regx.length() > 0) {
String regxArray[] = regx.split(",");
boolean ip_check = false;
for (int i = 0; i < regxArray.length; i++) {
Pattern p = Pattern.compile(regxArray[i]);
boolean flag = p.matcher(remoteAddr).find();
if (flag) {
ip_check = true;
break;
}
}
if (ip_check) {
System.out.println("IP校验通过!");
} else {
throw new AxisFault("",Messages.getMessage("wrong ip:"+remoteAddr),null,null);
}
} else {
System.out.println("请指定校验的客户端IP!");
throw new AxisFault();
}
} else if ("off".equalsIgnoreCase(switcher)) {
System.out.println("服务端IP校验开关处于【关闭】状态,不需要校验IP");
}
}
}
ip.properties
##################################IP校验配置##################################
#IP校验开关 只能填写on或者off,不区分大小写
ip_switcher=on
#允许调用对应的webservice服务的客户端IP地址 多个IP地址之间用逗号隔开
#当ip校验开关打开的时候,必须配置IP地址
ip_allow=10.10.147.124,10.10.147.123,127.0.0.1
##################################IP校验配置##################################
客户端文件
Test1.java
验证结果
发布工程,启动tomcat服务器:
1.看webservice在浏览器中是否可以正常显示
在浏览器中输入wsdl地址:
http://localhost:8080/WebService05_Security/services/HelloService?wsdl
2.运行webservice客户端,看是否可以正常的访问
目前IP配置文件中开关是打开的,并且127.0.0.1是允许访问此webservice服务的
运行后客户端和服务端日志分别如下:
3.模拟不能正常访问的IP地址的调用情况
把ip.properties文件中的
ip_allow=10.10.147.124,10.10.147.123,127.0.0.1
改为:
ip_allow=10.10.147.124,10.10.147.123
然后,重新发布项目,启动tomcat:
此时客户端和服务端的日志如下(此时需要时间稍微长一点,客户端才会出现以下异常):