在前面的文章中,我們實現了最簡單的AXIS服務。現在我們一起來討論一下Web服務的安全問題。
根據應用的對安全要求的級別不同,可以采用不同的方式來實現安全性,以下是目前最常用的一些實現方式(從低到高排列):
1、J2EE Web應用默認的訪問控制(數據是明文的);
2、使用axis的Handler進行訪問控制(數據是明文的);
3、使用Servlet過濾器(Filter)進行訪問控制(數據是明文的);
4、使用SSL/HTTPS協議來傳輸(加密的數據傳輸協議);
5、使用WS-Security規范對信息進行加密與身份認證(數據被加密傳輸)。
我們僅討論第2、4、5種實現方式。在此之前我們先來了解一下AXIS自帶的一個工具SOAPMonitor。
一、SOAPMonitor的使用
打開http://localhost:8080/axis/進入AXIS的主頁面,你會看見:
SOAPMonitor-[disabled by default for security reasons] ,默認狀態下其是不可用的,現在我們就來激活它。
1、到目錄%TOMCAT_HOME%\webapps\axis下,你會找到SOAPMonitorApplet.java,在命令行中編譯它:
javac -classpath %AXIS_HOME%\lib\axis.jar SOAPMonitorApplet.java
編譯完之后你會看見目錄下多了很多CLASS文件,它們的名字是SOAPMonitorApplet*.class
2、在目錄%TOMCAT_HOME%\webapps\axis\WEB-INF下打開server-config.wsdd文件,將下面的兩部分代碼直
接加入其中相應的位置
第一部分:
<handler name="soapmonitor" type="java:org.apache.axis.handlers.SOAPMonitorHandler">
<parameter name="wsdlURL" value="/axis/SOAPMonitorService-impl.wsdl"/>
<parameter name="namespace" value="http://tempuri.org/wsdl/2001/12/SOAPMonitorService-impl.wsdl"/>
<parameter name="serviceName" value="SOAPMonitorService"/>
<parameter name="portName" value="Demo"/>
</handler>
第二部分:
<service name="SOAPMonitorService" provider="java:RPC">
<parameter name="allowedMethods" value="publishMessage"/>
<parameter name="className" value="org.apache.axis.monitor.SOAPMonitorService"/>
<parameter name="scope" value="Application"/>
</service>
3、選擇你要監控的服務
以上次的HelloWorld服務為例,在server-config.wsdd中你會找到這段代碼
<service name="HelloWorld" provider="java:RPC">
<parameter name="allowedMethods" value="sayHello"/>
<parameter name="className" value="HelloWorld"/>
</service>
在這段代碼中加入以下的代碼:
<requestFlow>
<handler type="soapmonitor"/>
</requestFlow>
<responseFlow>
<handler type="soapmonitor"/>
</responseFlow>
最后的樣子是:
<service name="HelloWorld" provider="java:RPC">
<requestFlow>
<handler type="soapmonitor"/>
</requestFlow>
<responseFlow>
<handler type="soapmonitor"/>
</responseFlow>
<parameter name="allowedMethods" value="sayHello"/>
<parameter name="className" value="HelloWorld"/>
</service>
這樣HelloWorld服務就被監控了
4、啟動Tomcat,打開http://localhost:8080/axis/SOAPMonitor,你就會看到Applet界面,在
jbuilder2005中運行我們上次寫的客戶端程序 TestClient.java。OK!你會在Applet界面看
見客戶端與服務器端互發的XML內容,注意這里是明文!
二、使用axis的Handler進行訪問控制(對安全要求不高時推薦)
axis為Web服務的訪問控制提供了相關的配置描述符,并且提供了一個訪問控制的簡單 Handler。默認情況下,你只要在配置描述符中添加用戶,然后在Web服務器的部署描述符中自動允許的角色即可。
1、在axis的配置文件users.lst(位于WEB-INF目錄下)中添加一個用戶,如"ronghao1111",表示
用戶名為ronghao,密碼為1111。
2、把例HelloWorld的Web服務重新部署(新加的部分已標出)
<service name="HelloWorld" provider="java:RPC">
<requestFlow>
<handler type="soapmonitor"/>
<handler type="Authenticate"/> //新加的AXIS自帶的Handler
</requestFlow>
<responseFlow>
<handler type="soapmonitor"/>
</responseFlow>
<parameter name="allowedMethods" value="sayHello"/>
<parameter name="allowedRoles" value="ronghao"/> //注意,這里是新加的部分!
<parameter name="className" value="HelloWorld"/>
</service>
在這個部署描述符中,指定HelloWorld服務只能被ronghao訪問
3、修改客戶端程序 TestClient.java,增加訪問用戶名、密碼(新加的部分已標出)
TestClient.java
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.rpc.ParameterMode;
public class TestClient
{
public static void main(String [] args) throws Exception {
String endpoint = "http://localhost:" +"8080"+ "/axis/HelloWorld";
Service service = new Service();
Call call = (Call) service.createCall();
call.getMessageContext().setUsername("ronghao");// 用戶名。
call.getMessageContext().setPassword("1111");// 密碼
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName( "sayHello" );
String res = (String) call.invoke( new Object[] {} );
System.out.println( res );
}
}
執行TestClient,能夠順利訪問Web服務;如果修改用戶名或者密碼,那么就不能訪問 。同樣,
你在http://localhost:8080/axis/SOAPMonitor中看到的請求和響應的XML是明文!
三、使用SSL/HTTPS協議來傳輸
Web服務也可以使用SSL作為傳輸協議。雖然JAX-RPC并沒有強制規定是否使用SSL協議,但在tomcat 下使用HTTPS協議。
1、使用JDK自帶的工具創建密匙庫和信任庫。
1)通過使用以下的命令來創建服務器端的密匙庫:
keytool -genkey -alias Server -keystore server.keystore -keyalg RSA
輸入keystore密碼: changeit
您的名字與姓氏是什么?
[Unknown]: Server
您的組織單位名稱是什么?
[Unknown]: ec
您的組織名稱是什么?
[Unknown]: ec
您所在的城市或區域名稱是什么?
[Unknown]: beijing
您所在的州或省份名稱是什么?
[Unknown]: beijing
該單位的兩字母國家代碼是什么
[Unknown]: CN
CN=Server, OU=ec, O=ec, L=beijing, ST=beijing, C=CN 正確嗎?
[否]: y
輸入<Server>的主密碼
(如果和 keystore 密碼相同,按回車):
以上命令執行完成后,將獲得一個名為server.keystore的密匙庫。
2)生成客戶端的信任庫。首先輸出RSA證書:
keytool -export -alias Server -file test_axis.cer -storepass changeit -keystore server.keystore
然后把RSA證書輸入到一個新的信任庫文件中。這個信任庫被客戶端使用,被用來驗證服務器端的身份。
keytool -import -file test_axis.cer -storepass changeit -keystore client.truststore -alias serverkey -noprompt
以上命令執行完成后,將獲得一個名為client.truststore的信任庫。
3)同理生成客戶端的密匙庫client.keystore和服務器端的信任庫server.truststore.方便起見給出.bat文件
gen-cer-store.bat內容如下:
set SERVER_DN="CN=Server, OU=ec, O=ec, L=BEIJINGC, S=BEIJING, C=CN"
set CLIENT_DN="CN=Client, OU=ec, O=ec, L=BEIJING, S=BEIJING, C=CN"
set KS_PASS=-storepass changeit
set KEYINFO=-keyalg RSA
keytool -genkey -alias Server -dname %SERVER_DN% %KS_PASS% -keystore server.keystore %KEYINFO% -keypass changeit
keytool -export -alias Server -file test_axis.cer %KS_PASS% -keystore server.keystore
keytool -import -file test_axis.cer %KS_PASS% -keystore client.truststore -alias serverkey -noprompt
keytool -genkey -alias Client -dname %CLIENT_DN% %KS_PASS% -keystore client.keystore %KEYINFO% -keypass changeit
keytool -export -alias Client -file test_axis.cer %KS_PASS% -keystore client.keystore
keytool -import -file test_axis.cer %KS_PASS% -keystore server.truststore -alias clientkey -noprompt
好的,現在我們就有了四個文件:server.keystore,server.truststore,client.keystore,client.truststore
2、更改Tomcat的配置文件(server.xml),增加以下部署描述符:(其實里面有,只是被注釋掉了)
<Connector port="8440"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="true" keystoreFile="f:\server.keystore" keystorePass="changeit"
truststoreFile="f:\server.truststore" truststorePass="changeit"
sslProtocol="TLS" />
3、把HelloWorld重新部署一次,在server-config.wsdd中修改如下部署代碼。(還原了而已)
<service name="HelloWorld" provider="java:RPC">
<requestFlow>
<handler type="soapmonitor"/>
</requestFlow>
<responseFlow>
<handler type="soapmonitor"/>
</responseFlow>
<parameter name="allowedMethods" value="sayHello"/>
<parameter name="className" value="HelloWorld"/>
</service>
4、修改客戶端程序 TestClient.java(修改的部分已標出)
public class TestClient
{
public static void main(String [] args) throws Exception {
String endpoint = "https://localhost:" +"8440"+ "/axis/HelloWorld";//注意區別在這里!https!
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName( "sayHello" );
String res = (String) call.invoke( new Object[] {} );
System.out.println( res );
}
}
5、最后使用命令來執行客戶端程序
java -cp %AXISCLASSPATH%
-Djavax.net.ssl.keyStore=client.keystore
-Djavax.net.ssl.keyStorePassword=changeit
-Djavax.net.ssl.trustStore=client.truststore
TestClient
http://www.aygfsteel.com/ronghao 榮浩原創,轉載請注明出處:)