本節摘要:本節介紹使用handler的方式來實現webservice的IP地址的校驗。
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配置沒任何區別

1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.4" 3 xmlns="http://java.sun.com/xml/ns/j2ee" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 6 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 7 8 <servlet> 9 <servlet-name>AxisServlet</servlet-name> 10 <servlet-class> 11 org.apache.axis.transport.http.AxisServlet 12 </servlet-class> 13 </servlet> 14 <servlet-mapping> 15 <servlet-name>AxisServlet</servlet-name> 16 <url-pattern>/services/*</url-pattern> 17 </servlet-mapping> 18 19 </web-app>
server-config.wsdd---axis的配置文件,這里的配置就是一個webservice+handler的基本配置

1 <?xml version="1.0" encoding="UTF-8"?> 2 <deployment xmlns="http://xml.apache.org/axis/wsdd/" 3 xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> 4 <globalConfiguration> 5 <parameter name="sendMultiRefs" value="true" /> 6 <parameter name="disablePrettyXML" value="true" /> 7 <parameter name="adminPassword" value="admin" /> 8 <parameter name="attachments.Directory" 9 value="D:\tomcat5\webapps\WebService\WEB-INF\attachments" /> 10 <parameter name="dotNetSoapEncFix" value="true" /> 11 <parameter name="enableNamespacePrefixOptimization" 12 value="false" /> 13 <parameter name="sendXMLDeclaration" value="true" /> 14 <parameter name="sendXsiTypes" value="true" /> 15 <parameter name="attachments.implementation" 16 value="org.apache.axis.attachments.AttachmentsImpl" /> 17 <requestFlow> 18 <handler type="java:org.apache.axis.handlers.JWSHandler"> 19 <parameter name="scope" value="session" /> 20 </handler> 21 <handler type="java:org.apache.axis.handlers.JWSHandler"> 22 <parameter name="scope" value="request" /> 23 <parameter name="extension" value=".jwr" /> 24 </handler> 25 </requestFlow> 26 </globalConfiguration> 27 <handler name="LocalResponder" 28 type="java:org.apache.axis.transport.local.LocalResponder" /> 29 <handler name="URLMapper" 30 type="java:org.apache.axis.handlers.http.URLMapper" /> 31 <handler name="Authenticate" 32 type="java:org.apache.axis.handlers.SimpleAuthenticationHandler" /> 33 <service name="AdminService" provider="java:MSG"> 34 <parameter name="allowedMethods" value="AdminService" /> 35 <parameter name="enableRemoteAdmin" value="false" /> 36 <parameter name="className" value="org.apache.axis.utils.Admin" /> 37 <namespace>http://xml.apache.org/axis/wsdd/</namespace> 38 </service> 39 <service name="Version" provider="java:RPC"> 40 <parameter name="allowedMethods" value="getVersion" /> 41 <parameter name="className" value="org.apache.axis.Version" /> 42 </service> 43 44 <transport name="http"> 45 <requestFlow> 46 <handler type="URLMapper" /> 47 <handler 48 type="java:org.apache.axis.handlers.http.HTTPAuthHandler" /> 49 </requestFlow> 50 <parameter name="qs:list" 51 value="org.apache.axis.transport.http.QSListHandler" /> 52 <parameter name="qs:wsdl" 53 value="org.apache.axis.transport.http.QSWSDLHandler" /> 54 <parameter name="qs.list" 55 value="org.apache.axis.transport.http.QSListHandler" /> 56 <parameter name="qs.method" 57 value="org.apache.axis.transport.http.QSMethodHandler" /> 58 <parameter name="qs:method" 59 value="org.apache.axis.transport.http.QSMethodHandler" /> 60 <parameter name="qs.wsdl" 61 value="org.apache.axis.transport.http.QSWSDLHandler" /> 62 </transport> 63 <transport name="local"> 64 <responseFlow> 65 <handler type="LocalResponder" /> 66 </responseFlow> 67 </transport> 68 69 <!-- 配置一個handler,用來進行IP校驗--> 70 <handler name="IPHandler" type="java:server.handler.IpAuthentionHandler"> 71 <parameter name="status" value="success" /> 72 </handler> 73 74 75 <!-- 配置自己的服務 --> 76 <service name="HelloService" provider="java:RPC"> 77 <parameter name="allowedMethods" value="*" /> 78 <parameter name="className" value="server.service.HelloServiceImpl" /> 79 80 <!-- 引入IP校驗的handler --> 81 <requestFlow> 82 <handler type="IPHandler" /> 83 </requestFlow> 84 85 </service> 86 87 </deployment>
服務端文件
服務類:
HelloServiceImpl.java

1 package server.service; 2 3 public class HelloServiceImpl { 4 5 public String hello(String s) { 6 System.out.println("我是服務端......"); 7 System.out.println("方法的入參為:"+s); 8 return "hello," + s; 9 } 10 }
handler處理類和配置文件:
IpAuthentionHandler.java

1 package server.handler; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.util.Properties; 6 import java.util.regex.Pattern; 7 8 import javax.servlet.http.HttpServletRequest; 9 10 import org.apache.axis.AxisFault; 11 import org.apache.axis.MessageContext; 12 import org.apache.axis.handlers.BasicHandler; 13 import org.apache.axis.transport.http.HTTPConstants; 14 import org.apache.axis.utils.Messages; 15 16 //利用handler進行客戶端IP校驗 17 public class IpAuthentionHandler extends BasicHandler { 18 19 private static final long serialVersionUID = 1L; 20 21 private static Properties p = new Properties(); 22 23 static { 24 InputStream in = null; 25 try { 26 //注意這里的文件的存放位置和文件路徑的書寫方式; path 不以'/'開頭時默認是從此類所在的包下取資源 27 //這里如果我們把ip.properties放在src根目錄下,然后采用src/ip.properties的形式是沒法取到此文件的; 28 //此時需要使用 in=IpAuthentionHandler.class.getClassLoader().getResourceAsStream("ip.properties"); 29 in = IpAuthentionHandler.class.getResourceAsStream("ip.properties"); 30 p.load(in); 31 } catch (IOException e) { 32 System.out.println("ip.properties配置文件加載失敗!"); 33 e.printStackTrace(); 34 } finally { 35 if (null != in) 36 try { 37 in.close(); 38 } catch (IOException e) { 39 System.out.println("關閉流操作發生異常!"); 40 e.printStackTrace(); 41 } 42 } 43 } 44 45 public void invoke(MessageContext messageContext) throws AxisFault { 46 String status=(String)this.getOption("status"); 47 System.out.println("IpAuthentionHandler's status is :"+status); 48 49 String uri = messageContext.getSOAPActionURI(); 50 String targetService = messageContext.getTargetService(); 51 52 System.out.println("webservice開始IP認證:service>>" + uri + "/"+ targetService); 53 String name = HTTPConstants.MC_HTTP_SERVLETREQUEST; 54 55 HttpServletRequest request = (HttpServletRequest) messageContext 56 .getProperty(name); 57 String remoteAddr = request.getRemoteAddr(); 58 System.out.println("客戶端IP:" + remoteAddr); 59 60 String switcher = p.getProperty("ip_switcher"); 61 System.out.println("IP校驗開關:" + switcher); 62 63 if ("on".equalsIgnoreCase(switcher)) { 64 System.out.println("服務端IP校驗開關處於【打開】狀態,需要校驗IP"); 65 66 String regx = p.getProperty("ip_allow"); 67 System.out.println("允許調用服務的IP地址有:" + regx); 68 69 if (null != regx && regx.length() > 0) { 70 71 String regxArray[] = regx.split(","); 72 boolean ip_check = false; 73 for (int i = 0; i < regxArray.length; i++) { 74 Pattern p = Pattern.compile(regxArray[i]); 75 boolean flag = p.matcher(remoteAddr).find(); 76 if (flag) { 77 ip_check = true; 78 break; 79 } 80 } 81 82 if (ip_check) { 83 System.out.println("IP校驗通過!"); 84 } else { 85 throw new AxisFault("",Messages.getMessage("wrong ip:"+remoteAddr),null,null); 86 } 87 } else { 88 System.out.println("請指定校驗的客戶端IP!"); 89 throw new AxisFault(); 90 } 91 } else if ("off".equalsIgnoreCase(switcher)) { 92 System.out.println("服務端IP校驗開關處於【關閉】狀態,不需要校驗IP"); 93 } 94 } 95 96 }
ip.properties

1 ##################################IP校驗配置################################## 2 #IP校驗開關 只能填寫on或者off,不區分大小寫 3 ip_switcher=on 4 5 #允許調用對應的webservice服務的客戶端IP地址 多個IP地址之間用逗號隔開 6 #當ip校驗開關打開的時候,必須配置IP地址 7 ip_allow=10.10.147.124,10.10.147.123,127.0.0.1 8 9 ##################################IP校驗配置##################################
客戶端文件
Test1.java

1 package client; 2 3 import java.net.URL; 4 5 import javax.xml.rpc.ParameterMode; 6 7 import org.apache.axis.client.Call; 8 import org.apache.axis.encoding.XMLType; 9 10 public class Test1 { 11 12 public static void main(String args[]) throws Exception { 13 webservice_user(); 14 } 15 16 public static void webservice_user() throws Exception { 17 18 // 1.創建service對象,通過axis自帶的類創建 19 org.apache.axis.client.Service service = new org.apache.axis.client.Service(); 20 21 // 2.創建url對象 22 String wsdlUrl = "http://localhost:8080/WebService05_Security/services/HelloService?wsdl";// 請求服務的URL 23 URL url = new URL(wsdlUrl);// 通過URL類的構造方法傳入wsdlUrl地址創建URL對象 24 25 // 2.創建服務方法的調用者對象call,設置call對象的屬性 26 Call call = (Call) service.createCall(); 27 call.setTargetEndpointAddress(url);// 給call對象設置請求的URL屬性 28 String serviceName = "hello";// webservice的方法名 29 call.setOperationName(serviceName);// 給call對象設置調用方法名屬性 30 call.addParameter("s", XMLType.XSD_STRING, ParameterMode.IN);// 給call對象設置方法的參數名、參數類型、參數模式 31 call.setReturnType(XMLType.SOAP_STRING);// 設置調用方法的返回值類型 32 // call.setTimeout(new Integer(200));//設置超時限制 33 34 // 4.通過invoke方法調用webservice 35 String str = new String("pantp"); 36 String dept = (String) call.invoke(new Object[] { str });// 調用服務方法 37 38 // 5.打印返回結果 39 System.out.println("我是客戶端......."); 40 System.out.println(dept); 41 } 42 43 }
驗證結果
發布工程,啟動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:
此時客戶端和服務端的日志如下(此時需要時間稍微長一點,客戶端才會出現以下異常):