欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

webservice安全之cxf用wss4j加密

程序员文章站 2022-07-14 22:42:08
...

wss4j是在ws-security规范基础上对axis的安全应用。同样也可用于CXF上,本章讲在cxf上的使用,之后会讲解在axis上应用。

首先要生成公钥和密钥我在可以放在bat文件中放在项目中,此方式是自动生成的。

在项目中建立key文件夹,之后放入key.bat和serverKey.bat两个bat文件

key.bat内容如下:

rem @echooff
echo alias%1
echo keypass%2
echo keystoreName%3
echo KeyStorePass%4
echo keyName%5
echo keyName%5
keytool -genkey -alias %1 -keypass %2 -keystore %3 -storepass %4 -dname "cn=%1" -keyalg RSA
keytool -selfcert -alias %1 -keystore %3 -storepass %4 -keypass %2
keytool -export -alias %1 -file %5 -keystore %3 -storepass %4

serverKey.bat内容如下:注意一定将项目的工程空间加上

call workspace/cxfSecurity/key/key.bat serverAlias aliaspass workspace/cxfSecurity/key/serverStore.jks keystorePass workspace/cxfSecurity/key/serverKey.rsa
call workspace/cxfSecurity/key/keybat client-344-839 client344Password workspace/cxfSecurity/key/clientStore.jks keystorePass workspace/cxfSecurity/key/clientKey.rsa
keytool -import -alias serverAlias -file workspace/cxfSecurity/key/serverKey.rsa -keystore workspace/cxfSecurity/key/clientStore.jks -storepass keystorePass -noprompt
keytool -import -alias client-344-839 -file workspace/cxfSecurity/key/clientKey.rsa -keystore workspace/cxfSecurity/key/serverStore.jks -storepass keystorePass -noprompt


之后生成的clientStore.jks和serverStore.jks文件考到src目录下

建立两个outsecurity_sign.properties和server_insecurity_sign.propertues文件放在client的目录下和src目录下

内容如下:

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=clientStore.jks

另一个

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

配置clientApplicationContext.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="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/beans http://www.springframework.org/schema/beans/spring-beans.xsd      http://cxf.apache.org/jaxws      http://cxf.apache.org/schemas/jaxws.xsd">
 <bean id="client" class="jp.co.apm.service.impl.TestServiceImpl" factory-bean="clientFactory" factory-method="create"/>
 <bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
  <property name="serviceClass" value="jp.co.apm.service.TestService">
  </property>
  <property name="address" value="http://localhost:8088/services/test">
  </property>
  <property name="outInterceptors">
   <list>
    <bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor"/>
    <ref bean="wss4jOutConfiguration"/>
   </list>
  </property>
 </bean>
 <bean id="wss4jOutConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
  <property name="properties">
   <map>
    <entry key="action" value="Signature"/>
    <entry key="user" value="client-344-839"/>
    <entry key="passwordType" value="PasswordDigest"/>
    <entry key="signatureKeyIdentifier" value="IssuerSerial"/>
    <entry key="signaturePropFile" value="client/outsecurity_sign.properties"/>
    <entry>
     <key>
      <value>passwordCallbackRef</value>
     </key>
     <ref bean="passwordCallback"/>
    </entry>
   </map>
  </property>
 </bean>
 <bean id="passwordCallback" class="security.PasswordCallbackHandler"/>

</beans>

PasswordCallbackHandler类放在security目录下

package security;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;

public class PasswordCallbackHandler implements CallbackHandler {
 private Map<String, String> passwords = new HashMap<String, String>();

 public PasswordCallbackHandler() {
  passwords.put("serveralias", "aliaspass");
  passwords.put("client-344-839", "client344Password");
 }

 public void handle(Callback[] callbacks) throws IOException,
   UnsupportedCallbackException {
  WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
  String id = pc.getIdentifer();
  pc.setPassword((String) passwords.get(id));
 }
}

然后就写一个服务类

package service;
import javax.jws.WebService;
@WebService
public interface TestService{
 public String sayHello() throws javax.xml.ws.WebServiceException;
}

package service.impl;
import javax.jws.WebService;
import jp.co.apm.service.TestService;

@WebService
public class TestServiceImpl implements TestService{
 public String sayHello(){
  return "Hello,ShenBin";
 }
}
之后是cxf-servlet.xml文件发布服务的 放在webinfo下

<?xml version="1.0" encoding="UTF-8"?>
<beans  xmlns="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/beans http://www.springframework.org/schema/beans/spring-beans.xsd  http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

  <import resource="classpath:META-INF/cxf/cxf.xml"/>
  <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
  <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
  <jaxws:endpoint id="testservice" implementor="jp.co.apm.service.impl.TestServiceImpl" address="/test">
   <jaxws:features>
       <bean class="org.apache.cxf.feature.LoggingFeature"/>
      </jaxws:features>
   <jaxws:inInterceptors>
    <bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/>  
        <ref bean="wss4jInConfiguration"/>
      </jaxws:inInterceptors>
  </jaxws:endpoint>
  <bean id="wss4jInConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
   <property name="properties">
    <map>
     <entry key="action" value="Signature"/>
     <!-- 
          <entrykey="user"value="client-344-839"/>
          <entrykey="passwordType"value="PasswordDigest"/>
         -->
     <entry key="signaturePropFile" value="server_insecurity_sign.properties"/>
     <entry>
      <key><value>passwordCallbackRef</value></key>
      <ref bean="passwordCallback"/>
     </entry>
    </map>
   </property>
  </bean>
  <bean id="passwordCallback" class="jp.co.apm.security.PasswordCallbackHandler"/>
</beans>

最后就是web.xml了

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="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>

测试类如下

package client;

import javax.xml.ws.WebServiceException;

import jp.co.apm.service.TestService;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestServiceClient {
 public static void main(String[] args) {
  ApplicationContext context = new ClassPathXmlApplicationContext(
    new String[] { "jp/co/apm/client/clientApplicationContext.xml" });
  TestService service = (TestService) context.getBean("client");
  try {
   System.out.println(service.sayHello());
  } catch (WebServiceException e) {
   e.printStackTrace();
  }
 }
}
这就完成了,最好跟着做一下,如果要源代码,可以留言