[置顶]       webservice的安全机制2---handler实现

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

项目结构图如下:


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:

此时客户端和服务端的日志如下(此时需要时间稍微长一点,客户端才会出现以下异常):






你可能感兴趣的:(java,webservice,安全,web服务)