posts - 193,  comments - 520,  trackbacks - 0


          在前面的文章中,我們實(shí)現(xiàn)了最簡(jiǎn)單的
          AXIS服務(wù)。現(xiàn)在我們一起來討論一下Web服務(wù)的安全問題。
          根據(jù)應(yīng)用的對(duì)安全要求的級(jí)別不同,可以采用不同的方式來實(shí)現(xiàn)安全性,以下是目前最常用的一些實(shí)現(xiàn)方式(從低到高排列):
              1
          J2EE Web應(yīng)用默認(rèn)的訪問控制(數(shù)據(jù)是明文的); 
              2
          、使用axisHandler進(jìn)行訪問控制(數(shù)據(jù)是明文的); 
              3
          、使用Servlet過濾器(Filter)進(jìn)行訪問控制(數(shù)據(jù)是明文的); 
              4
          、使用SSL/HTTPS協(xié)議來傳輸(加密的數(shù)據(jù)傳輸協(xié)議); 
              5
          、使用WS-Security規(guī)范對(duì)信息進(jìn)行加密與身份認(rèn)證(數(shù)據(jù)被加密傳輸)。
          我們僅討論第245種實(shí)現(xiàn)方式。在此之前我們先來了解一下AXIS自帶的一個(gè)工具SOAPMonitor
          一、SOAPMonitor的使用
            
          打開http://localhost:8080/axis/進(jìn)入AXIS的主頁面,你會(huì)看見:
             SOAPMonitor-[disabled by default for security reasons] 
          ,默認(rèn)狀態(tài)下其是不可用的,現(xiàn)在我們就來激活它。
             
          1
          、到目錄%TOMCAT_HOME%\webapps\axis下,你會(huì)找到SOAPMonitorApplet.java,在命令行中編譯它:   


          javac -classpath %AXIS_HOME%\lib\axis.jar SOAPMonitorApplet.java
           
             編譯完之后你會(huì)看見目錄下多了很多CLASS文件,它們的名字是SOAPMonitorApplet*.class

          2
          、在目錄%TOMCAT_HOME%\webapps\axis\WEB-INF下打開server-config.wsdd文件,將下面的兩部分代碼直
             
          接加入其中相應(yīng)的位置
             
          第一部分:
           

          <
          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
          、選擇你要監(jiān)控的服務(wù)
             
          以上次的HelloWorld服務(wù)為例,在server-config.wsdd中你會(huì)找到這段代碼
             
          <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服務(wù)就被監(jiān)控了
             
          4
          、啟動(dòng)Tomcat,打開http://localhost:8080/axis/SOAPMonitor,你就會(huì)看到Applet界面,在
             jbuilder2005
          中運(yùn)行我們上次寫的客戶端程序 TestClient.javaOK!你會(huì)在Applet界面看
             
          見客戶端與服務(wù)器端互發(fā)的XML內(nèi)容,注意這里是明文!
             
          二、使用axisHandler進(jìn)行訪問控制(對(duì)安全要求不高時(shí)推薦)
             axis
          Web服務(wù)的訪問控制提供了相關(guān)的配置描述符,并且提供了一個(gè)訪問控制的簡(jiǎn)單  Handler。默認(rèn)情況下,你只要在配置描述符中添加用戶,然后在Web服務(wù)器的部署描述符中自動(dòng)允許的角色即可。

          1
          、在axis的配置文件users.lst(位于WEB-INF目錄下)中添加一個(gè)用戶,如"ronghao1111",表示
             
          用戶名為ronghao,密碼為1111
             
          2
          、把例HelloWorldWeb服務(wù)重新部署(新加的部分已標(biāo)出)
             
          <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>

            
          在這個(gè)部署描述符中,指定HelloWorld服務(wù)只能被ronghao訪問
             
          3
          、修改客戶端程序 TestClient.java,增加訪問用戶名、密碼(新加的部分已標(biāo)出)
            
          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 );
             }
          }

            
          執(zhí)行TestClient,能夠順利訪問Web服務(wù);如果修改用戶名或者密碼,那么就不能訪問 。同樣,
            
          你在http://localhost:8080/axis/SOAPMonitor中看到的請(qǐng)求和響應(yīng)的XML是明文!
            
          三、使用SSL/HTTPS協(xié)議來傳輸
              Web
          服務(wù)也可以使用SSL作為傳輸協(xié)議。雖然JAX-RPC并沒有強(qiáng)制規(guī)定是否使用SSL協(xié)議,但在tomcat 下使用HTTPS協(xié)議。
          1
          、使用JDK自帶的工具創(chuàng)建密匙庫和信任庫。

            1
          )通過使用以下的命令來創(chuàng)建服務(wù)器端的密匙庫:
           
           keytool 
          -genkey -alias Server -keystore server.keystore -keyalg RSA
            輸入keystore密碼:  changeit
            您的名字與姓氏是什么?
            [Unknown]:  Server
            您的組織單位名稱是什么?
            [Unknown]:  ec
            您的組織名稱是什么?
            [Unknown]:  ec
            您所在的城市或區(qū)域名稱是什么?
            [Unknown]:  beijing
            您所在的州或省份名稱是什么?
            [Unknown]:  beijing
            該單位的兩字母國(guó)家代碼是什么
            [Unknown]:  CN
          CN
          =Server, OU=ec, O=ec, L=beijing, ST=beijing, C=CN 正確嗎?
            [否]:  y

          輸入
          <Server>的主密碼
                  (如果和 keystore 密碼相同,按回車):

             
          以上命令執(zhí)行完成后,將獲得一個(gè)名為server.keystore的密匙庫。
             
            2)
          生成客戶端的信任庫。首先輸出RSA證書:
           

          keytool 
          -export -alias Server -file test_axis.cer -storepass changeit -keystore server.keystore

            
          然后把RSA證書輸入到一個(gè)新的信任庫文件中。這個(gè)信任庫被客戶端使用,被用來驗(yàn)證服務(wù)器端的身份。
           

          keytool 
          -import -file test_axis.cer -storepass changeit -keystore client.truststore -alias serverkey -noprompt

            
          以上命令執(zhí)行完成后,將獲得一個(gè)名為client.truststore的信任庫。
            
            3
          )同理生成客戶端的密匙庫client.keystore和服務(wù)器端的信任庫server.truststore.方便起見給出.bat文件
               gen-cer-store.bat
          內(nèi)容如下:
              
               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

               
            
          好的,現(xiàn)在我們就有了四個(gè)文件:server.keystoreserver.truststoreclient.keystoreclient.truststore
            
          2
          、更改Tomcat的配置文件(server.xml),增加以下部署描述符:(其實(shí)里面有,只是被注釋掉了)
               
          <
          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(修改的部分已標(biāo)出)


          public
           class TestClient
          {
             
          public static void main(String [] args) throws Exception {
             String endpoint 
          = "https://localhost:" +"8440"+ "/axis/HelloWorld";//注意區(qū)別在這里!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
          、最后使用命令來執(zhí)行客戶端程序

          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 榮浩原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處:)
          posted on 2007-06-12 16:10 ronghao 閱讀(3946) 評(píng)論(4)  編輯  收藏 所屬分類: SOA、BPM

          FeedBack:
          # re: 建立安全的AXIS服務(wù)(上)
          2007-06-14 00:09 | IT進(jìn)行時(shí)
          寫的不錯(cuò),清晰  回復(fù)  更多評(píng)論
            
          # re: 建立安全的AXIS服務(wù)(上)
          2008-06-02 17:08 | isle_t
          5、最后使用命令來執(zhí)行客戶端程序

          這一步中的%AXISCLASSPATH%是指什么,能說得詳細(xì)點(diǎn)嗎,有點(diǎn)搞不懂  回復(fù)  更多評(píng)論
            
          # re: 建立安全的AXIS服務(wù)(上)[未登錄]
          2012-08-03 15:32 | 蟈蟈
          樓主你好:
          我嘗試你的方法結(jié)果在:
          二、使用axis的Handler進(jìn)行訪問控制(對(duì)安全要求不高時(shí)推薦) 加了用戶驗(yàn)證后客戶端訪問會(huì)報(bào)錯(cuò):
          xisFault
          faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
          faultSubcode:
          faultString: org.apache.axis.ConfigurationException: Can't find handler name:'null' type:'Authenticate' in the registry
          org.apache.axis.ConfigurationException: Can't find handler name:'null' type:'Authenticate' in the registry
          at org.apache.axis.deployment.wsdd.WSDDChain.makeNewInstance(WSDDChain.java:129)
          at org.apache.axis.deployment.wsdd.WSDDDeployableItem.getNewInstance(WSDDDeployableItem.java:274)
          at org.apache.axis.deployment.wsdd.WSDDDeployableItem.getInstance(WSDDDeployableItem.java:260)
          at org.apache.axis.deployment.wsdd.WSDDService.makeNewInstance(WSDDService.java:430)
          at org.apache.axis.deployment.wsdd.WSDDDeployableItem.getNewInstance(WSDDDeployableItem.java:274)
          at org.apache.axis.deployment.wsdd.WSDDDeployableItem.getInstance(WSDDDeployableItem.java:260)
          at org.apache.axis.deployment.wsdd.WSDDDeployment.getService(WSDDDeployment.java:427)
          at org.apache.axis.configuration.FileProvider.getService(FileProvider.java:231)
          at org.apache.axis.AxisEngine.getService(AxisEngine.java:311)
          at org.apache.axis.MessageContext.setTargetService(MessageContext.java:756)
          at org.apache.axis.handlers.http.URLMapper.invoke(URLMapper.java:50)
          at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
          at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
          at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
          at org.apache.axis.server.AxisServer.invoke(AxisServer.java:239)
          at org.apache.axis.transport.http.AxisServlet.doPost(AxisServlet.java:699)
          at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
          at org.apache.axis.transport.http.AxisServletBase.service(AxisServletBase.java:327)
          at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
          at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
          at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
          at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
          at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
          at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
          at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
          at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
          at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
          at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874)
          at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
          at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
          at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
          at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
          at java.lang.Thread.run(Thread.java:619)
            回復(fù)  更多評(píng)論
            
          # re: 建立安全的AXIS服務(wù)(上)[未登錄]
          2012-08-03 17:21 | 蟈蟈
          我加入以下代碼后,前面的問題解決了。
          <handler name="Authenticate"
          type="java:org.apache.axis.handlers.SimpleAuthenticationHandler" />   回復(fù)  更多評(píng)論
            
          <2007年6月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

          關(guān)注工作流和企業(yè)業(yè)務(wù)流程改進(jìn)。現(xiàn)就職于ThoughtWorks。新浪微博:http://weibo.com/ronghao100

          常用鏈接

          留言簿(38)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          常去的網(wǎng)站

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 海原县| 玉树县| 永城市| 鲜城| 怀来县| 乐安县| 思南县| 邹城市| 古浪县| 顺昌县| 贺兰县| 玛纳斯县| 那坡县| 大安市| 宝山区| 平阴县| 新化县| 宣汉县| 平利县| 红原县| 华坪县| 吉首市| 保康县| 巢湖市| 宜兴市| 西吉县| 普格县| 南昌县| 外汇| 南部县| 翼城县| 陇川县| 闵行区| 泾川县| 五常市| 新沂市| 隆回县| 延边| 无锡市| 长葛市| 龙里县|