建立安全的AXIS服务(上)

在前面的文章中,我们实现了最简单的 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值