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调用成功!

相关推荐