我的漫漫程序之旅

          專注于JavaWeb開發
          隨筆 - 39, 文章 - 310, 評論 - 411, 引用 - 0
          數據加載中……

          實施WebService Security[WS-Security1.0]的Encrypt和Sign模式(XFire+WSS4J)

          鑒于很多系統需要實施WS-Security的標準,我們在SpringSide中提供了XFire+WSS4J的Demo,本文介紹SpringSide中Spring+XFire+WSS4J的基本配置

          [WebService Server端配置]
          第一,創建一個基本的BookService
          public interface BookService {
              
          /**
               * 按書名模糊查詢圖書
               
          */

              List findBooksByName(String name);

              
          /**
               * 查找目錄下的所有圖書
               *
               * 
          @param categoryId 如果category為null或“all”, 列出所有圖書。
               
          */

              List findBooksByCategory(String categoryId);

              
          /**
               * 列出所有分類.
               *
               * 
          @return List<Category>,或是null。
               
          */

              List getAllCategorys();
          }

          第二,接口擴展,即Extend基本的BookService,在XFire中,不同的WSS4J策略需要針對不同的ServiceClass,否則<inHandlers>里面的定義會Overlap。
          public interface BookServiceWSS4JEnc  extends BookService {

          }

          public interface BookServiceWSS4JSign  extends BookService {

          }

          第三,配置Spring的ApplicationContext文件
              <!--BookService 基類-->
              
          <bean id="baseWebService" class="org.codehaus.xfire.spring.remoting.XFireExporter" abstract="true">
                  
          <property name="serviceFactory" ref="xfire.serviceFactory"/>
                  
          <property name="xfire" ref="xfire"/>
              
          </bean>

              
          <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
                  
          <property name="mappings">
                      
          <value>
                          /BookService=bookService
                          /BookServiceWSS4J=bookServiceWSS4J
                          /BookServiceWSS4JEnc=bookServiceWSS4JEnc
                          /BookServiceWSS4JSign=bookServiceWSS4JSign
                      
          </value>
                  
          </property>
              
          </bean>

             
          <!--(1)BookWebService 不需要認證-->
              
          <bean id="bookService" class="org.codehaus.xfire.spring.remoting.XFireExporter">
                  
          <property name="serviceFactory" ref="xfire.serviceFactory"/>
                  
          <property name="xfire" ref="xfire"/>
                  
          <property name="serviceBean" ref="bookManager"/>
                  
          <property name="serviceClass" value="org.springside.bookstore.plugins.xfire.service.BookService"/>
              
          </bean>

              
          <!--  (3)BookWebService 使用 WSS4J驗證-->
              
          <bean id="bookServiceWSS4J" class="org.codehaus.xfire.spring.remoting.XFireExporter">
                  
          <property name="serviceBean" ref="bookManager"/>
                  
          <property name="serviceClass" value="org.springside.bookstore.plugins.xfire.service.BookServiceWSS4J"/>
                  
          <property name="inHandlers">
                      
          <list>
                          
          <ref bean="domInHandler"/>
                          
          <ref bean="wss4jInHandler"/>
                          
          <ref bean="validateUserTokenHandler"/>
                      
          </list>
                  
          </property>
              
          </bean>

              
          <bean id="domInHandler" class="org.codehaus.xfire.util.dom.DOMInHandler"/>

              
          <bean id="wss4jInHandler" class="org.codehaus.xfire.security.wss4j.WSS4JInHandler">
                  
          <property name="properties">
                      
          <props>
                          
          <prop key="action">UsernameToken</prop>
                          
          <prop key="passwordCallbackClass">org.springside.bookstore.plugins.xfire.wss4j.PasswordHandler</prop>
                      
          </props>
                  
          </property>
              
          </bean>

              
          <bean id="validateUserTokenHandler" class="org.springside.bookstore.plugins.xfire.wss4j.WSS4JTokenHandler"/>
              
              
          <!--  (4)BookWebService 使用 WSS4J驗證 Encrypt模式-->
              
          <bean id="bookServiceWSS4JEnc" class="org.codehaus.xfire.spring.remoting.XFireExporter">
                  
          <property name="serviceBean" ref="bookManager"/>
                  
          <property name="serviceClass" value="org.springside.bookstore.plugins.xfire.service.BookServiceWSS4JEnc"/>
                  
          <property name="inHandlers">
                      
          <list>
                          
          <ref bean="domInHandler"/>
                          
          <ref bean="wss4jInHandlerEnc"/>
                          
          <ref bean="validateUserTokenHandler"/>
                      
          </list>
                  
          </property>
              
          </bean>
                  
              
          <bean id="wss4jInHandlerEnc" class="org.codehaus.xfire.security.wss4j.WSS4JInHandler">
                  
          <property name="properties">
                    
          <props>
                      
          <prop key="action">Encrypt</prop>
                      
          <prop key="decryptionPropFile">org/springside/bookstore/plugins/xfire/wss4j/insecurity_enc.properties</prop>
                      
          <prop key="passwordCallbackClass">org.springside.bookstore.plugins.xfire.wss4j.PasswordHandler</prop>
                    
          </props>
                  
          </property>
              
          </bean>
              
              
          <!--  (5)BookWebService 使用 WSS4J驗證 Signature模式-->
              
          <bean id="bookServiceWSS4JSign" class="org.codehaus.xfire.spring.remoting.XFireExporter">
                  
          <property name="serviceBean" ref="bookManager"/>
                  
          <property name="serviceClass" value="org.springside.bookstore.plugins.xfire.service.BookServiceWSS4JSign"/>
                  
          <property name="inHandlers">
                      
          <list>
                          
          <ref bean="domInHandler"/>
                          
          <ref bean="wss4jInHandlerSign"/>
                          
          <ref bean="validateUserTokenHandler"/>
                      
          </list>
                  
          </property>
              
          </bean>
              
              
          <bean id="wss4jInHandlerSign" class="org.codehaus.xfire.security.wss4j.WSS4JInHandler">
                  
          <property name="properties">
                    
          <props>
                      
          <prop key="action">Signature</prop>
                      
          <prop key="signaturePropFile">org/springside/bookstore/plugins/xfire/wss4j/insecurity_sign.properties</prop>
                      
          <prop key="passwordCallbackClass">org.springside.bookstore.plugins.xfire.wss4j.PasswordHandler</prop>
                    
          </props>
                  
          </property>
              
          </bean>
              
          </beans>

          第四,配置insecurity_enc.properties和insecurity_sign.properties兩個密鑰庫配置文件
          insecurity_enc.properties:
          org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
          org.apache.ws.security.crypto.merlin.keystore.type
          =jks
          org.apache.ws.security.crypto.merlin.keystore.password
          =SpringSide
          org.apache.ws.security.crypto.merlin.alias.password
          =SpringSide
          org.apache.ws.security.crypto.merlin.keystore.alias
          =david
          org.apache.ws.security.crypto.merlin.file
          =org/springside/bookstore/plugins/xfire/wss4j/springside_private.jks

          outsecurity_sign.properties:
          org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
          org.apache.ws.security.crypto.merlin.keystore.type
          =jks
          org.apache.ws.security.crypto.merlin.keystore.password
          =SpringSide
          org.apache.ws.security.crypto.merlin.keystore.alias
          =david
          org.apache.ws.security.crypto.merlin.file
          =org/springside/bookstore/plugins/xfire/wss4j/springside_public.jks

          第五,使用SecureX生成了兩個keystore文件
          springside_private.jks
          別名名稱: david
          創建日期: 
          2006-8-6
          輸入類型:KeyEntry
          認證鏈長度: 
          1
          認證 
          [1]:
          Owner: CN
          =david, OU=SpringSide, O=org, L=gz, ST=gd, C=cn
          發照者: CN
          =david, OU=SpringSide, O=org, L=gz, ST=gd, C=cn
          序號: 44d4cdcd
          有效期間: Sun Aug 
          06 00:56:45 CST 2006 至: Mon Aug 06 00:56:45 CST 2007
          認證指紋:
                   MD5:  CF:
          97:13:0C:70:D0:4D:B6:B4:27:0F:1A:0B:CF:D9:F2
                   SHA1: 8E:8E:E8:BC:
          64:39:C8:43:E4:F7:1B:3B:CE:48:1D:6B:A0:2B:58:B5

          springside_public.jks
          別名名稱: david
          創建日期: 
          2006-8-6
          輸入類型: trustedCertEntry

          Owner: CN
          =david, OU=SpringSide, O=org, L=gz, ST=gd, C=cn
          發照者: CN
          =david, OU=SpringSide, O=org, L=gz, ST=gd, C=cn
          序號: 44d4cdcd
          有效期間: Sun Aug 
          06 00:56:45 CST 2006 至: Mon Aug 06 00:56:45 CST 2007
          認證指紋:
                   MD5:  CF:
          97:13:0C:70:D0:4D:B6:B4:27:0F:1A:0B:CF:D9:F2
                   SHA1: 8E:8E:E8:BC:
          64:39:C8:43:E4:F7:1B:3B:CE:48:1D:6B:A0:2B:58:B5

          第五,新版本SpringSide需要
          http://www.bouncycastle.org/download/bcprov-jdk15-133.jar
          并且要配置java.security
          另外,還要使用jdk加密增強策略
          http://www.aygfsteel.com/openssl/archive/2006/03/08/34381.html

          用戶要使用WSS4J,需要配置Bouncycastle這個SecurityProvider,否則
          運行Enc模式的XFire認證的時候,會拋出異常:
          org.apache.ws.security.WSSecurityException: An unsupported signature or encryption algorithm was used unsupported key
          配合java.security也是非常簡單:
          在最后加入BouncycastleProvider。
          security.provider.1=sun.security.provider.Sun
          security.provider.2=com.sun.net.ssl.internal.ssl.Provider
          security.provider.3=com.sun.rsajca.Provider
          security.provider.4=com.sun.crypto.provider.SunJCE
          security.provider.5=sun.security.jgss.SunProvider
          security.provider.6=org.bouncycastle.jce.provider.BouncyCastleProvider

          [WebService Client端配置]
          1,Encrypt模式的Client是在客戶端用david的公鑰加密Soap里面的usernameToken,然后發送到Web服務,Web服務用david的私鑰來驗證。這種模式需要客戶端預先知道服務器端的公鑰。

          在Encrypt模式中,需要這樣配置ClientHandler:
                  Service serviceModel = new ObjectServiceFactory().create(BookServiceWSS4JEnc.class);
                  XFireProxyFactory factory 
          = new XFireProxyFactory(getXFire());

                  BookService service 
          = (BookService) factory.create(serviceModel, "xfire.local://BookServiceWSS4JEnc");

                  Client client 
          = ((XFireProxy) Proxy.getInvocationHandler(service)).getClient();
                  
          //掛上WSS4JOutHandler,提供認證
                  client.addOutHandler(new DOMOutHandler());
                  Properties properties 
          = new Properties();
                  configureOutProperties(properties);
                  client.addOutHandler(
          new WSS4JOutHandler(properties));

                  List list 
          = service.getAllCategorys();
          configureOutProperties函數負責指定Client使用何種安全策略,沒錯,使用outsecurity_enc.properties,這個properties是跟Server端的insecurity_enc.properties一起使用的。
              protected void configureOutProperties(Properties config) {
                  config.setProperty(WSHandlerConstants.ACTION, WSHandlerConstants.ENCRYPT);
                  config.setProperty(WSHandlerConstants.USER, 
          "david");
                  
          //config.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS, PasswordHandler.class.getName());
                  
          //Configuration of public key used to encrypt message goes to properties file.
                  config.setProperty(WSHandlerConstants.ENC_PROP_FILE,
                                         
          "org/springside/bookstore/plugins/xfire/outsecurity_enc.properties");
              }

          outsecurity_enc.properties:
          org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
          org.apache.ws.security.crypto.merlin.keystore.type
          =jks
          org.apache.ws.security.crypto.merlin.keystore.password
          =SpringSide
          org.apache.ws.security.crypto.merlin.keystore.alias
          =david
          org.apache.ws.security.crypto.merlin.file
          =org/springside/bookstore/plugins/xfire/wss4j/springside_public.jks


          2, Sign模式的Client同樣也是很簡單,這種模式是Client端用自己的私鑰為usernameToken簽名,服務器端用Client的公鑰來驗證簽名,因此,服務器端需要預先知道客戶端的公鑰。
          對應于Encrypt模式,這里的configureOutProperties需要這樣來配置:
              protected void configureOutProperties(Properties properties) {
                  properties.setProperty(WSHandlerConstants.ACTION,WSHandlerConstants.SIGNATURE);
                  
          // User in keystore
                  properties.setProperty(WSHandlerConstants.USER, "david");
                  
          // This callback is used to specify password for given user for keystore
                  properties.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS, PasswordHandler.class.getName());
                  
          // Configuration for accessing private key in keystore
                  properties.setProperty(WSHandlerConstants.SIG_PROP_FILE,"org/springside/bookstore/plugins/xfire/outsecurity_sign.properties");
                  properties.setProperty(WSHandlerConstants.SIG_KEY_ID,
          "IssuerSerial");
              }


          outsecurity_sign.properties:
          org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
          org.apache.ws.security.crypto.merlin.keystore.type
          =jks
          org.apache.ws.security.crypto.merlin.keystore.password
          =SpringSide
          org.apache.ws.security.crypto.merlin.alias.password
          =SpringSide
          org.apache.ws.security.crypto.merlin.keystore.alias
          =david
          org.apache.ws.security.crypto.merlin.file
          =org/springside/bookstore/plugins/xfire/wss4j/springside_private.jks


          posted on 2008-05-07 11:08 々上善若水々 閱讀(1303) 評論(1)  編輯  收藏 所屬分類: WebService

          評論

          # re: 實施WebService Security[WS-Security1.0]的Encrypt和Sign模式(XFire+WSS4J)   回復  更多評論   

          能給我一個完整的SpringSide + Web Services + WS-Security 和 客戶端調用 的代碼嗎 ,非常感謝您
          郵箱:guowei821120@163.com
          2008-07-15 22:59 | 過為
          主站蜘蛛池模板: 敦煌市| 长乐市| 崇明县| 和平县| 桐柏县| 宽甸| 剑阁县| 沧州市| 龙门县| 隆安县| 鹤岗市| 从化市| 五莲县| 习水县| 漾濞| 吉水县| 安庆市| 宜阳县| 靖江市| 长丰县| 玉田县| 高阳县| 延安市| 宁津县| 闻喜县| 瓮安县| 温泉县| 周宁县| 屏东县| 本溪市| 卢氏县| 阿拉善右旗| 安阳市| 巍山| 余姚市| 郁南县| 龙州县| 泽普县| 道真| 保亭| 盘锦市|