CXF开通用户认证
第一部分:环境
1.系统版本:Fedora14
2.Eclipse版本:J2ee版3.5
3.jdk版本:jdk1.6
4.mavenlocalrepository:/var/javaproject/repo
5.tomcat版本:1.6
6.tomcat端口:9080
假设以上环境已经安装完毕,各软件能独立正确运行。
第二部分:配置eclipse工作区
在适当的地方建立一个cxftest目录,然后在此目录再建一个cxftest_build目录
在cxftest_build目录中建立pom.xml文件,输入一下内容:
<!--subpom.xmlstart--->
<?xmlversion="1.0"encoding="UTF-8"?>
<projectxmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bruce.cxftest</groupId>
<artifactId>cxftest_build</artifactId>
<packaging>pom</packaging>
<name>cxftestParentProject</name>
<version>1.0-SNAPSHOT</version>
<modules>
<module>../cxftest_public_impl</module>
<module>../cxftest_public_intf</module>
<module>../cxftest_web</module>
<module>../cxftest_client</module>
</modules>
<properties>
<wss4j.version>1.6.4</wss4j.version>
<spring.version>3.0.2.RELEASE</spring.version>
<cxf.version>2.5.2</cxf.version>
<junit.version>4.8.1</junit.version>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
</dependencies>
</project>
<!--subpom.xmlend--->
我的电脑最终目录结构为:
cxftest/
|/cxftest_build
|/cxftest_client
|/cxftest_public_impl
|/cxftest_public_intf
|/cxftest_web
并以cxftest目录为基础建立eclipse工作区
第二部分:开发公共接口项目
在eclipse中建立名为cxftest_public_intf的java工程,设置java源文件的目录为/src/main/java,资源目录为/src/main/resorces
在cxftest_public_intf项目根目录建立名为pom.xml输入以下内容:
<!--pom.xmlstart→
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bruce.cxftest</groupId>
<version>1.0-SNAPSHOT</version>
<artifactId>cxftest_build</artifactId>
<relativePath>../cxftest_build/pom.xml</relativePath>
</parent>
<artifactId>cxftest_public_intf</artifactId>
<packaging>jar</packaging>
<name>cxftestwebserviceinterfaceProject</name>
<build>
<finalName>${artifactId}-${version}</finalName>
<defaultGoal>process-resources</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf.version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${basedir}/src/main/java</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/src/main/wsdl/service.wsdl</wsdl>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
</dependencies>
</project>
<!--pom.xmlend-->
用eclipse自带的工具src/main/wsdl目录编辑wsdl文件service.wsdl与dto.xsd:
<!--service.wsdlstart-->
<?xmlversion="1.0"?>
<wsdl:definitionstargetNamespace="http://www.bruce.com/cxftest/service"
xmlns:service="http://www.bruce.com/cxftest/service"
xmlns:dto="http://www.bruce.com/cxftest/dto"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<wsdl:types>
<xsd:schemaxmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:importnamespace="http://www.bruce.com/cxftest/dto"schemaLocation="dto.xsd">
</xsd:import>
</xsd:schema>
</wsdl:types>
<wsdl:messagename="GetPhoneRequest">
<wsdl:partname="name"element="dto:getPhoneRequest"/>
</wsdl:message>
<wsdl:messagename="GetPhoneResponse">
<wsdl:partname="phone"element="dto:getPhoneResponse"/>
</wsdl:message>
<wsdl:portTypename="AddressBookService">
<wsdl:operationname="getPhone">
<wsdl:inputmessage="service:GetPhoneRequest"/>
<wsdl:outputmessage="service:GetPhoneResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:bindingname="AddressBook"type="service:AddressBookService">
<soap:bindingstyle="document"transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operationname="getPhone">
<soap:operation
soapAction="http://www.bruce.com/cxftest/service/getPhone"/>
<wsdl:input>
<soap:bodyuse="literal"/>
</wsdl:input>
<wsdl:output>
<soap:bodyuse="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:servicename="AddressBookService">
<wsdl:portname="AddressBookService"binding="service:AddressBook">
<soap:addresslocation="http://www.bruce.com/"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
<!--service.wsdlend-->
<!--dto.xsdstart-->
<?xmlversion="1.0"?>
<xsd:schematargetNamespace="http://www.bruce.com/cxftest/dto"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:dto="http://www.bruce.com/cxftest/dto">
<xsd:complexTypename="Phone">
<xsd:sequence>
<xsd:elementname="areaCode"type="xsd:int"/>
<xsd:elementname="exchange"type="xsd:int"/>
<xsd:elementname="number"type="xsd:int"/>
<xsd:elementname="date"type="xsd:date"></xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:elementname="getPhoneRequest"type="xsd:string"></xsd:element>
<xsd:elementname="getPhoneResponse"type="dto:Phone"></xsd:element>
</xsd:schema>
<!--dto.xsdend-->
在目录cxftest/cxftest_public_intf/下运行:
#mvninstall
以生成Webservice的接口与Dto类。
第三部分:开发公共实现项目
在eclipse中建立名为cxftest_public_impl的java工程,设置java源文件的目录为/src/main/java,资源目录为/src/main/resorces
在cxftest_public_impl项目根目录建立名为pom.xml输入以下内容:
<!--pom.xmlstart→
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bruce.cxftest</groupId>
<version>1.0-SNAPSHOT</version>
<artifactId>cxftest_build</artifactId>
<relativePath>../cxftest_build/pom.xml</relativePath>
</parent>
<artifactId>cxftest_public_impl</artifactId>
<packaging>jar</packaging>
<name>cxftestwebserviceimplementProject</name>
<build>
<finalName>${artifactId}-${version}</finalName>
<defaultGoal>process-resources</defaultGoal>
<plugins>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.bruce.cxftest</groupId>
<version>${version}</version>
<artifactId>cxftest_public_intf</artifactId>
</dependency>
<dependency>
<groupId>org.apache.ws.security</groupId>
<artifactId>wss4j</artifactId>
<version>${wss4j.version}</version>
</dependency>
</dependencies>
</project>
<!--pom.xmlend-->
建立服务实现类com.bruce.cxftest.service.AddressBookServiceImpl,输入以下内容(这个类应该也有相应的工具生成,但是我还没找到):
//**************AddressBookServiceImplstart********************
packagecom.bruce.cxftest.service;
importcom.bruce.cxftest.dto.Phone;
publicclassAddressBookServiceImplimplementsAddressBookService{
@Override
publicPhonegetPhone(Stringname){
Phonephone;
System.out.println(name);
phone=newPhone();
phone.setAreaCode(120);
phone.setExchange(10);
phone.setNumber(10);
returnphone;
}
}
//**************AddressBookServiceImplend********************
建立服务端用户回调类类com.bruce.cxftest.security.ServerPasswordCallback,输入以下内容(这个类应该也有相应的工具生成,但是我还没找到):
//**************ServerPasswordCallbackstart********************
packagecom.bruce.cxftest.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;
publicclassServerPasswordCallbackimplementsCallbackHandler{
Map<String,String>userMap=newHashMap<String,String>();
publicServerPasswordCallback(){
userMap.put("joe","password");
}
publicvoidhandle(Callback[]callbacks)throwsIOException,
UnsupportedCallbackException{
WSPasswordCallbackpc=(WSPasswordCallback)callbacks[0];
if(userMap.containsKey(pc.getIdentifier())){
pc.setPassword(userMap.get(pc.getIdentifier()));
}
}
}
第四部分:开发公共WEB服务项目
在eclipse中建立名为cxftest_web的java工程,设置java源文件的目录为/src/main/java,资源文件目录为/src/main/resources.
目录结构为:
cxftest_web
/src
|/main
|/java
|/resources
/WebContent
/WEB-INF
/classes
/lib
在cxftest_web项目根目录建立名为pom.输入以下内容:
<!--pom.xmlstart-->
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bruce.cxftest</groupId>
<version>1.0-SNAPSHOT</version>
<artifactId>cxftest_build</artifactId>
<relativePath>../cxftest_build/pom.xml</relativePath>
</parent>
<artifactId>cxftest_web</artifactId>
<packaging>war</packaging>
<name>cxftestwebProject</name>
<build>
<finalName>${artifactId}-${version}</finalName>
<defaultGoal>process-resources</defaultGoal>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warSourceDirectory>${basedir}/WebContent</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.bruce.cxftest</groupId>
<version>${version}</version>
<artifactId>cxftest_public_intf</artifactId>
</dependency>
<dependency>
<groupId>com.bruce.cxftest</groupId>
<version>${version}</version>
<artifactId>cxftest_public_impl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-core</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-common-utilities</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-policy</artifactId>
<version>${cxf.version}</version>
</dependency>
</dependencies>
</project>
<!--pom.xmlend-->
建立Service配置文件/src/main/resources/applicationContext-server.xml,输入以下内容:
<!--*******applicationContext-server.xmlstart*************-->
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.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"/>
<beanid="addressBookServiceImpl"class="com.bruce.cxftest.service.AddressBookServiceImpl"/>
<beanid="myPasswordCallback"class="com.bruce.cxftest.security.ServerPasswordCallback"/>
<beanid="sAAJInInterceptor"class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/>
<beanid="wSS4JInInterceptor"class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entrykey="action"value="UsernameToken"/>
<entrykey="passwordType"value="PasswordDigest"/>
<entrykey="passwordCallbackRef">
<refbean="myPasswordCallback"/>
</entry>
</map>
</constructor-arg>
</bean>
<jaxws:endpointid="addressBookService"implementor="#addressBookServiceImpl"
address="/AddressBookService">
<jaxws:inInterceptors>
<refbean="sAAJInInterceptor"/>
<refbean="wSS4JInInterceptor"/>
</jaxws:inInterceptors>
</jaxws:endpoint>
</beans>
<!--********applicationContext-server.xmlend************-->
5在目录/WebContent/WEB-INF下创建名为web.xml的文件,输入以下内容:
<!--web.xml**********start-->
<?xmlversion="1.0"encoding="UTF-8"?>
<web-appxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID"version="2.5">
<display-name>xfireserver</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:applicationContext-server.xml
classpath:META-INF/cxf/cxf-extension-policy.xml
classpath:META-INF/cxf/cxf-extension-ws-security.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
<!--web.xml**********end-->
第五部分:开发webservice服务客户端
在eclipse中建立名为cxftest_client的java工程,设置java源文件的目录为/src/main/java,资源目录为/src/main/resources.
目录结构为:
cxftest_client
/src
/main
/java
/resources
在cxftest_client项目根目录建立名为pom.输入以下内容:
<!--pom.xmlstart-->
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bruce.cxftest</groupId>
<version>1.0-SNAPSHOT</version>
<artifactId>cxftest_build</artifactId>
<relativePath>../cxftest_build/pom.xml</relativePath>
</parent>
<artifactId>cxftest_client</artifactId>
<packaging>jar</packaging>
<name>cxftestclientProject</name>
<build>
<finalName>${artifactId}-${version}</finalName>
<defaultGoal>process-resources</defaultGoal>
<plugins>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.bruce.cxftest</groupId>
<version>${version}</version>
<artifactId>cxftest_public_intf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.ws.security</groupId>
<artifactId>wss4j</artifactId>
<version>${wss4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
<version>${cxf.version}</version>
</dependency>
</dependencies>
</project>
<!--pom.xmlend-->
建立服务测试类SpringUsersWsClient.java,输入以下内容
//**************SpringUsersWsClientstart********************
packagecom.bruce.cxftest.client;
importorg.springframework.beans.BeansException;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.ClassPathXmlApplicationContext;
importcom.bruce.cxftest.dto.Phone;
importcom.bruce.cxftest.service.AddressBookService;
publicclassSpringUsersWsClient{
publicstaticvoidmain(String[]args){
try{
ApplicationContextctx=newClassPathXmlApplicationContext("applicationContext-client.xml");
AddressBookServiceservice=ctx.getBean("addressBookClient",AddressBookService.class);
System.out.println("#############ClientgetPhone##############");
Phonephone=service.getPhone("zph");
System.out.println("AreaCode:"+phone.getAreaCode());
System.out.println("Exchange:"+phone.getExchange());
System.out.println("Number:"+phone.getNumber());
}catch(BeansExceptione){
e.printStackTrace();
}
}
}
//**************SpringUsersWsClientend********************
建立用户认证回调类ServerPasswordCallback.java,输入以下内容
//**************ServerPasswordCallbackstart********************
packagecom.bruce.cxftest.security;
importjava.io.IOException;
importjavax.security.auth.callback.Callback;
importjavax.security.auth.callback.CallbackHandler;
importjavax.security.auth.callback.UnsupportedCallbackException;
importorg.apache.ws.security.WSPasswordCallback;
publicclassServerPasswordCallbackimplementsCallbackHandler{
Stringusername="joe";
Stringpassword="password";
publicStringgetUserName(){
returnuserName;
}
publicvoidsetUserName(StringuserName){
this.userName=userName;
}
publicStringgetPassword(){
returnpassword;
}
publicvoidsetPassword(Stringpassword){
this.password=password;
}
publicvoidhandle(Callback[]callbacks)throwsIOException,UnsupportedCallbackException{
WSPasswordCallbackpc=(WSPasswordCallback)callbacks[0];
pc.setPassword(password);
pc.setIdentifier(userName);
}
}
//**************ServerPasswordCallbackend********************
建立ClientService配置文件/src/main/resources/applicationContext-client.xml,输入以下内容:
<!--*******applicationContext-client.xmlstart*************-->
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<beanid="myPasswordCallback"class="com.bruce.cxftest.security.ServerPasswordCallback"/>
<beanid="wSS4JOutInterceptor"class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entrykey="action"value="UsernameToken"/>
<entrykey="passwordType"value="PasswordDigest"/>
<entrykey="user"value="joe"/>
<entrykey="passwordCallbackRef">
<refbean="myPasswordCallback"/>
</entry>
</map>
</constructor-arg>
</bean>
<jaxws:clientid="addressBookClient"
serviceclass="com.bruce.cxftest.service.AddressBookService"
address="http://127.0.0.1:9080/cxftest/service/AddressBookService">
<jaxws:outInterceptors>
<refbean="wSS4JOutInterceptor"/>
</jaxws:outInterceptors>
</jaxws:client>
</beans>
<!--********applicationContext-client.xmlend************-->
第六部分:调试运行
1.打开命令行转至cxftest_build目录,运行如下命令
$mvncleaninstall
$mvneclipse:eclipse
2.将打好的Wea包拷贝至Tomcatwebapps目录下的cxftest目录中。
3.启动Tomcat
4.启动cxftest_client工程里的SpringUsersWsClient类:输出如下信息:
AreaCode:120
Exchange:10
Number:10
至此表明Webservice调用成功!