Apache CXF支持WS-Security规范
新建2个批处理文件用以生成服务端及客户端密钥文件。generateKeyPair.bat
rem@echooff
echoalias%1
echokeypass%2
echokeystoreName%3
echoKeyStorePass%4
echokeyName%5
echokeyName%5
keytool-genkey-alias%1-keypass%2-keystore%3-storepass%4 -dname"cn=%1"-keyalgRSA
keytool-selfcert-alias%1-keystore%3-storepass%4-keypass%2
keytool-export-alias%1-file%5-keystore%3-storepass%4
generateServerKey.bat
callgenerateKeyPair.batserverAliasaliaspassserverStore.jkskeystorePassserverKey.rsa
callgenerateKeyPair.batclient-344-839 client344Password clientStore.jkskeystorePassclientKey.rsa
keytool-import-aliasserverAlias-fileserverKey.rsa-keystoreclientStore.jks-storepasskeystorePass-noprompt
keytool-import-aliasclient-344-839-fileclientKey.rsa-keystoreserverStore.jks-storepasskeystorePass-noprompt
注意:
生成的密钥文件中包含的信息:
服务端 账户:serverAlias / aliaspass
客户端 账户:client-344-839 / client344Password
依次运行后生成serverStore.jks和clientStore.jks这2个文件待用。
如下图所示建立工程:
http://img.ddvip.com/2009_02_04/1233728045_ddvip_7982..jpg
XmlSchema-1.4.2.jar
commons-logging-1.1.1.jar
cxf-2.0.9.jar
jaxb-impl-2.0.5.jar
jaxws-api-2.0.jar
neethi-2.0.4.jar
opensaml-1.1.jar
saaj-api-1.3.jar
saaj-impl-1.3.jar
serializer-2.7.1.jar
spring-beans-2.0.8.jar
spring-context-2.0.8.jar
spring-core-2.0.8.jar
spring-web-2.0.8.jar
wsdl4j-1.6.2.jar
wss4j-1.5.4.jar
xalan-2.7.1.jar
xml-resolver-1.2.jar
xmlsec-1.4.0.jar
代码如下:
TestServiceClient.java
packagejp.co.apm.client;
importjp.co.apm.service.TestService;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.ClassPathXmlApplicationContext;
publicclassTestServiceClient{
publicstaticvoidmain(String[]args){
ApplicationContextcontext=newClassPathXmlApplicationContext(
newString[]{"jp/co/apm/client/clientApplicationContext.xml"});
TestServiceservice=(TestService)context.getBean("client");
System.out.println(service.sayHello());
}
}
clientApplicationContext.xml
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxwshttp://cxf.apache.org/schemas/jaxws.xsd">
<beanid="client"class="jp.co.apm.service.impl.TestServiceImpl"factory-bean="clientFactory"factory-method="create"/>
<beanid="clientFactory"class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<propertyname="serviceClass"value="jp.co.apm.service.TestService">
</property>
<propertyname="address"
value="http://localhost:8080/APM_CXF/services/test">
</property>
<propertyname="outInterceptors">
<list>
<beanclass="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor"/>
<refbean="wss4jOutConfiguration"/>
</list>
</property>
</bean>
<beanid="wss4jOutConfiguration"class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<propertyname="properties">
<map>
<entrykey="action"value="Signature"/>
<entrykey="user"value="client-344-839"/>
<entrykey="passwordType"value="PasswordDigest"/>
<entrykey="signatureKeyIdentifier"value="IssuerSerial"/>
<entrykey="signaturePropFile"value="jp/co/apm/client/outsecurity_sign.properties"/>
<entry>
<key>
<value>passwordCallbackRef</value>
</key>
<refbean="passwordCallback"/>
</entry>
</map>
</property>
</bean>
<beanid="passwordCallback"class="jp.co.apm.security.PasswordCallbackHandler"/>
</beans>
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=keystorePass
org.apache.ws.security.crypto.merlin.alias.password=client344Password
org.apache.ws.security.crypto.merlin.keystore.alias=client-344-839
org.apache.ws.security.crypto.merlin.file=jp/co/apm/client/clientStore.jks
以下是服务端代码:
PasswordCallbackHandler.java
packagejp.co.apm.security;
importjava.io.IOException;
importjava.util.HashMap;
importjava.util.Map;
importjavax.security.auth.callback.Callback;
importjavax.security.auth.callback.CallbackHandler;
importjavax.security.auth.callback.UnsupportedCallbackException;
importorg.apache.ws.security.WSPasswordCallback;
publicclassPasswordCallbackHandlerimplementsCallbackHandler{
privateMap<String,String>passwords=newHashMap<String,String>();
publicPasswordCallbackHandler(){
passwords.put("serveralias","aliaspass");
passwords.put("client-344-839","client344Password");
}
publicvoidhandle(Callback[]callbacks)throwsIOException,UnsupportedCallbackException{
WSPasswordCallbackpc=(WSPasswordCallback)callbacks;
Stringid=pc.getIdentifer();
pc.setPassword((String)passwords.get(id));
}
}
TestServiceImpl.java
packagejp.co.apm.service.impl;
importjavax.jws.WebService;
importjp.co.apm.service.TestService;
@WebService
publicclassTestServiceImplimplementsTestService{
publicStringsayHello(){
return"Hello,ShenBin";
}
}
TestService.java
packagejp.co.apm.service;
importjavax.jws.WebService;
@WebService
publicinterfaceTestService{
publicStringsayHello();
}
server_insecurity_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=keystorePass
#org.apache.ws.security.crypto.merlin.alias.password=aliaspass
org.apache.ws.security.crypto.merlin.keystore.alias=serveralias
org.apache.ws.security.crypto.merlin.file=serverStore.jks
cxf-servlet.xml
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxwshttp://cxf.apache.org/schemas/jaxws.xsd">
<importresource="classpath:META-INF/cxf/cxf.xml"/>
<importresource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
<importresource="classpath:META-INF/cxf/cxf-servlet.xml"/>
<jaxws:endpointid="testservice"implementor="jp.co.apm.service.impl.TestServiceImpl"address="/test">
<jaxws:features>
<beanclass="org.apache.cxf.feature.LoggingFeature"/>
</jaxws:features>
<jaxws:inInterceptors>
<beanclass="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/>
<refbean="wss4jInConfiguration"/>
</jaxws:inInterceptors>
</jaxws:endpoint>
<beanid="wss4jInConfiguration"class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<propertyname="properties">
<map>
<entrykey="action"value="Signature"/>
<!--
<entrykey="user"value="client-344-839"/>
<entrykey="passwordType"value="PasswordDigest"/>
-->
<entrykey="signaturePropFile"value="server_insecurity_sign.properties"/>
<entry>
<key>
<value>passwordCallbackRef</value>
</key>
<refbean="passwordCallback"/>
</entry>
</map>
</property>
</bean>
<beanid="passwordCallback"class="jp.co.apm.security.PasswordCallbackHandler"/>
</beans>
web.xml
<?xmlversion="1.0"encoding="UTF-8"?>
<web-appversion="2.5"xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>APM</display-name>
<description>APM</description>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/cxf-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>APM</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>APM</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
</web-app>
差点忘了一个最重要的环节,就是要在java.security中追加一个解密算法的支持:
jrelibsecurityjava.security文件中,追加类似如下语句:
.....
security.provider.5=sun.security.jgss.SunProvider
security.provider.6=com.sun.security.sasl.Provider
security.provider.7=org.bouncycastle.jce.provider.BouncyCastleProvider
页:
[1]