[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./download/bcprov-jdk15-133.jar 并且要配置java.security 另外,还要使用jdk加密增强策略 http://www./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);
configureOutProperties函数负责指定Client使用何种安全策略,没错,使用outsecurity_enc.properties,这个properties是跟Server端的insecurity_enc.properties一起使用的。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(); 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 |
|