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

鉴于很多系统需要实施WS-Security的标准,我们在SpringSide中提供了XFire+WSS4J的Demo,本文介绍SpringSide中Spring+XFire+WSS4J的基本配置

[WebService Server端配置]
第一,创建一个基本的BookService
ExpandedBlockStart.gif ContractedBlock.gif public   interface  BookService  dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** *//**
InBlock.gif     * 按书名模糊查询图书
ExpandedSubBlockEnd.gif     
*/

InBlock.gif    List findBooksByName(String name);
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** *//**
InBlock.gif     * 查找目录下的所有图书
InBlock.gif     *
InBlock.gif     * 
@param categoryId 如果category为null或“all”, 列出所有图书。
ExpandedSubBlockEnd.gif     
*/

InBlock.gif    List findBooksByCategory(String categoryId);
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** *//**
InBlock.gif     * 列出所有分类.
InBlock.gif     *
InBlock.gif     * 
@return List<Category>,或是null。
ExpandedSubBlockEnd.gif     
*/

InBlock.gif    List getAllCategorys();
ExpandedBlockEnd.gif}

第二,接口扩展,即Extend基本的BookService,在XFire中,不同的WSS4J策略需要针对不同的ServiceClass,否则<inHandlers>里面的定义会Overlap。
ExpandedBlockStart.gif ContractedBlock.gif public   interface  BookServiceWSS4JEnc   extends  BookService  dot.gif {
InBlock.gif
ExpandedBlockEnd.gif}

ExpandedBlockStart.gif ContractedBlock.gif public   interface  BookServiceWSS4JSign   extends  BookService  dot.gif {
InBlock.gif
ExpandedBlockEnd.gif}

第三,配置Spring的ApplicationContext文件
None.gif      <!-- BookService 基类 -->
None.gif    
< bean  id ="baseWebService"  class ="org.codehaus.xfire.spring.remoting.XFireExporter"  abstract ="true" >
None.gif        
< property  name ="serviceFactory"  ref ="xfire.serviceFactory" />
None.gif        
< property  name ="xfire"  ref ="xfire" />
None.gif    
</ bean >
None.gif
None.gif    
< bean  class ="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" >
None.gif        
< property  name ="mappings" >
None.gif            
< value >
None.gif                /BookService=bookService
None.gif                /BookServiceWSS4J=bookServiceWSS4J
None.gif                /BookServiceWSS4JEnc=bookServiceWSS4JEnc
None.gif                /BookServiceWSS4JSign=bookServiceWSS4JSign
None.gif            
</ value >
None.gif        
</ property >
None.gif    
</ bean >
None.gif
None.gif   
<!-- (1)BookWebService 不需要认证 -->
None.gif    
< bean  id ="bookService"  class ="org.codehaus.xfire.spring.remoting.XFireExporter" >
None.gif        
< property  name ="serviceFactory"  ref ="xfire.serviceFactory" />
None.gif        
< property  name ="xfire"  ref ="xfire" />
None.gif        
< property  name ="serviceBean"  ref ="bookManager" />
None.gif        
< property  name ="serviceClass"  value ="org.springside.bookstore.plugins.xfire.service.BookService" />
None.gif    
</ bean >
None.gif
None.gif    
<!--   (3)BookWebService 使用 WSS4J验证 -->
None.gif    
< bean  id ="bookServiceWSS4J"  class ="org.codehaus.xfire.spring.remoting.XFireExporter" >
None.gif        
< property  name ="serviceBean"  ref ="bookManager" />
None.gif        
< property  name ="serviceClass"  value ="org.springside.bookstore.plugins.xfire.service.BookServiceWSS4J" />
None.gif        
< property  name ="inHandlers" >
None.gif            
< list >
None.gif                
< ref  bean ="domInHandler" />
None.gif                
< ref  bean ="wss4jInHandler" />
None.gif                
< ref  bean ="validateUserTokenHandler" />
None.gif            
</ list >
None.gif        
</ property >
None.gif    
</ bean >
None.gif
None.gif    
< bean  id ="domInHandler"  class ="org.codehaus.xfire.util.dom.DOMInHandler" />
None.gif
None.gif    
< bean  id ="wss4jInHandler"  class ="org.codehaus.xfire.security.wss4j.WSS4JInHandler" >
None.gif        
< property  name ="properties" >
None.gif            
< props >
None.gif                
< prop  key ="action" > UsernameToken </ prop >
None.gif                
< prop  key ="passwordCallbackClass" > org.springside.bookstore.plugins.xfire.wss4j.PasswordHandler </ prop >
None.gif            
</ props >
None.gif        
</ property >
None.gif    
</ bean >
None.gif
None.gif    
< bean  id ="validateUserTokenHandler"  class ="org.springside.bookstore.plugins.xfire.wss4j.WSS4JTokenHandler" />
None.gif    
None.gif    
<!--   (4)BookWebService 使用 WSS4J验证 Encrypt模式 -->
None.gif    
< bean  id ="bookServiceWSS4JEnc"  class ="org.codehaus.xfire.spring.remoting.XFireExporter" >
None.gif        
< property  name ="serviceBean"  ref ="bookManager" />
None.gif        
< property  name ="serviceClass"  value ="org.springside.bookstore.plugins.xfire.service.BookServiceWSS4JEnc" />
None.gif        
< property  name ="inHandlers" >
None.gif            
< list >
None.gif                
< ref  bean ="domInHandler" />
None.gif                
< ref  bean ="wss4jInHandlerEnc" />
None.gif                
< ref  bean ="validateUserTokenHandler" />
None.gif            
</ list >
None.gif        
</ property >
None.gif    
</ bean >
None.gif        
None.gif    
< bean  id ="wss4jInHandlerEnc"  class ="org.codehaus.xfire.security.wss4j.WSS4JInHandler" >
None.gif        
< property  name ="properties" >
None.gif          
< props >
None.gif            
< prop  key ="action" > Encrypt </ prop >
None.gif            
< prop  key ="decryptionPropFile" > org/springside/bookstore/plugins/xfire/wss4j/insecurity_enc.properties </ prop >
None.gif            
< prop  key ="passwordCallbackClass" > org.springside.bookstore.plugins.xfire.wss4j.PasswordHandler </ prop >
None.gif          
</ props >
None.gif        
</ property >
None.gif    
</ bean >
None.gif    
None.gif    
<!--   (5)BookWebService 使用 WSS4J验证 Signature模式 -->
None.gif    
< bean  id ="bookServiceWSS4JSign"  class ="org.codehaus.xfire.spring.remoting.XFireExporter" >
None.gif        
< property  name ="serviceBean"  ref ="bookManager" />
None.gif        
< property  name ="serviceClass"  value ="org.springside.bookstore.plugins.xfire.service.BookServiceWSS4JSign" />
None.gif        
< property  name ="inHandlers" >
None.gif            
< list >
None.gif                
< ref  bean ="domInHandler" />
None.gif                
< ref  bean ="wss4jInHandlerSign" />
None.gif                
< ref  bean ="validateUserTokenHandler" />
None.gif            
</ list >
None.gif        
</ property >
None.gif    
</ bean >
None.gif    
None.gif    
< bean  id ="wss4jInHandlerSign"  class ="org.codehaus.xfire.security.wss4j.WSS4JInHandler" >
None.gif        
< property  name ="properties" >
None.gif          
< props >
None.gif            
< prop  key ="action" > Signature </ prop >
None.gif            
< prop  key ="signaturePropFile" > org/springside/bookstore/plugins/xfire/wss4j/insecurity_sign.properties </ prop >
None.gif            
< prop  key ="passwordCallbackClass" > org.springside.bookstore.plugins.xfire.wss4j.PasswordHandler </ prop >
None.gif          
</ props >
None.gif        
</ property >
None.gif    
</ bean >
None.gif    
None.gif
</ beans >
None.gif

第四,配置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
None.gif 别名名称: david
None.gif创建日期: 
2006 - 8 - 6
None.gif输入类型: trustedCertEntry
None.gif
None.gifOwner: CN
= david ,  OU = SpringSide ,  O = org ,  L = gz ,  ST = gd ,  C = cn
None.gif发照者: CN
= david ,  OU = SpringSide ,  O = org ,  L = gz ,  ST = gd ,  C = cn
None.gif序号: 44d4cdcd
None.gif有效期间: Sun Aug 
06   00 : 56 : 45  CST  2006  至: Mon Aug  06   00 : 56 : 45  CST  2007
None.gif认证指纹:
None.gif         MD5:  CF:
97 : 13 :0C: 70 :D0:4D:B6:B4: 27 :0F:1A:0B:CF:D9:F2
None.gif         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.blogjava.net/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:
None.gif         Service serviceModel  =   new  ObjectServiceFactory().create(BookServiceWSS4JEnc. class );
None.gif        XFireProxyFactory factory 
=   new  XFireProxyFactory(getXFire());
None.gif
None.gif        BookService service 
=  (BookService) factory.create(serviceModel,  " xfire.local://BookServiceWSS4JEnc " );
None.gif
None.gif        Client client 
=  ((XFireProxy) Proxy.getInvocationHandler(service)).getClient();
None.gif        
// 挂上WSS4JOutHandler,提供认证
None.gif
        client.addOutHandler( new  DOMOutHandler());
None.gif        Properties properties 
=   new  Properties();
None.gif        configureOutProperties(properties);
None.gif        client.addOutHandler(
new  WSS4JOutHandler(properties));
None.gif
None.gif        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:
None.gif org.apache.ws.security.crypto.provider = org.apache.ws.security.components.crypto.Merlin
None.giforg.apache.ws.security.crypto.merlin.keystore.type
= jks
None.giforg.apache.ws.security.crypto.merlin.keystore.password
= SpringSide
None.giforg.apache.ws.security.crypto.merlin.keystore.alias
= david
None.giforg.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
=
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值