网络当中搜索CXF Securiy的时候,有且只有一篇文章,所以决定自己写个可执行的demo放上来。
这次先放上网上盛传的那个demo,请勿转载,否则根本没法看了。
CXF相关介绍和接口就不介绍,直接上代码。
先放上wsdl,很简单,一个最简单的wsdl:
security.wsdl
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="security"
targetNamespace="http://demo.ti.tongtech.com/security/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://demo.ti.tongtech.com/security/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://demo.ti.tongtech.com/security/">
<xsd:element name="input">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="in" type="xsd:string"></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="inputResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="out" type="xsd:string"></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
<wsdl:message name="inputRequest">
<wsdl:part name="parameters" element="tns:input"></wsdl:part>
</wsdl:message>
<wsdl:message name="inputResponse">
<wsdl:part name="parameters" element="tns:inputResponse"></wsdl:part>
</wsdl:message>
<wsdl:portType name="ISecuriyDemo">
<wsdl:operation name="input">
<wsdl:input message="tns:inputRequest"></wsdl:input>
<wsdl:output message="tns:inputResponse"></wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ISecurityBinding" type="tns:ISecuriyDemo">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="input">
<soap:operation soapAction="http://demo.ti.tongtech.com/security/input" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ISecuriyService">
<wsdl:port name="ISecuriyServicePort" binding="tns:ISecurityBinding">
<soap:address location="http://localhost:8080/sec" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
使用cxf的wsdl2java生成服务接口和服务器端、客户端代码,这里我就不多说了,一会贴上maven的pom文件。
然后写客户端程序
Client.java
package com.tongtech.ti.demo.security.ut.client;
/**
* Please modify this class to meet your needs
* This class is not complete
*/
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.xml.namespace.QName;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.handler.WSHandlerConstants;
import com.tongtech.ti.demo.security.service.ISecuriyDemo;
import com.tongtech.ti.demo.security.service.ISecuriyService;
/**
* This class was generated by Apache CXF 2.4.0-SNAPSHOT Fri Oct 22 15:44:43 CST
* 2010 Generated source version: 2.4.0-SNAPSHOT
*
*/
public final class Client {
private static final QName SERVICE_NAME = new QName(
"http://demo.ti.tongtech.com/security/", "ISecuriyService");
private Client() {
}
public static void main(String args[]) throws Exception {
URL wsdlURL = ISecuriyService.WSDL_LOCATION;
//获取endpoint,并加入WSS4J的Intercepter
ISecuriyService ss = new ISecuriyService(wsdlURL, SERVICE_NAME);
ISecuriyDemo port = ss.getISecuriyServicePort();
Map<String, Object> outProp = new HashMap<String, Object>();
outProp
.put(WSHandlerConstants.ACTION,
WSHandlerConstants.USERNAME_TOKEN);
outProp.put(WSHandlerConstants.USER, "SecuriyUserName");
outProp.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
outProp.put(WSHandlerConstants.PW_CALLBACK_CLASS,
UTPasswordClientCallBack.class.getName());
org.apache.cxf.endpoint.Client client = ClientProxy.getClient(port);
Endpoint cxfEp = client.getEndpoint();
cxfEp.getOutInterceptors().add(new WSS4JOutInterceptor(outProp));
//调用服务接口
{
System.out.println("Invoking input...");
java.lang.String _input_in = "Input value!";
java.lang.String _input__return = port.input(_input_in);
System.out.println("input.result=" + _input__return);
}
System.exit(0);
}
}
客户端代码是根据CXF生成的代码改的。
接下来是CallBackHandler
UTPasswordClientCallBack.java
package com.tongtech.ti.demo.security.ut.client;
import java.io.IOException;
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 UTPasswordClientCallBack implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
pc.setPassword("password");
System.out.println("UserName=" + pc.getIdentifier());
System.out.println("Password=" + pc.getPassword());
}
}
下面是服务端代码:
Server.java
package com.tongtech.ti.demo.security.ut.server;
import java.util.HashMap;
import java.util.Map;
import javax.xml.ws.Endpoint;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.handler.WSHandlerConstants;
import com.tongtech.ti.demo.security.service.ISecuriyDemoImpl;
/**
* This class was generated by Apache CXF 2.4.0-SNAPSHOT Fri Oct 22 15:44:43 CST
* 2010 Generated source version: 2.4.0-SNAPSHOT
*
*/
public class Server {
protected Server() throws Exception {
System.out.println("Starting Server");
Object implementor = new ISecuriyDemoImpl();
String address = "http://localhost:8080/sec";
EndpointImpl ep = (EndpointImpl) Endpoint.publish(address, implementor);
org.apache.cxf.endpoint.Endpoint cxfEp = ep.getServer().getEndpoint();
Map<String, Object> inProp = new HashMap<String, Object>();
inProp
.put(WSHandlerConstants.ACTION,
WSHandlerConstants.USERNAME_TOKEN);
inProp.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
inProp.put(WSHandlerConstants.PW_CALLBACK_CLASS,
UTPasswordServerCallBack.class.getName());
cxfEp.getInInterceptors().add(new WSS4JInInterceptor(inProp));
}
public static void main(String args[]) throws Exception {
new Server();
System.out.println("Server ready...");
Thread.sleep(60 * 60 * 1000);
System.out.println("Server exiting");
System.exit(0);
}
}
接下来是服务端的CallBackHandler
UTPasswordServerCallBack.java
package com.tongtech.ti.demo.security.ut.server;
import java.io.IOException;
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 UTPasswordServerCallBack implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
System.out.println("UserName=" + pc.getIdentifier());
System.out.println("Password=" + pc.getPassword());
}
}
代码献上了,如何使用这些代码,下面简单说下:
先给出Maven的Pom文件:
<project xmlns="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>ti-cxf</groupId>
<artifactId>ti-cxf-security</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Tongtech Demo for CXF Security with wss4j</name>
<properties>
<cxf.version>2.4.0-SNAPSHOT</cxf.version>
</properties>
<dependencies>
<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.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version>
</dependency>
</dependencies>
<build>
<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.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf.version}</version>
<executions>
<execution>
<id>generate-sources-static</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${basedir}/target/generate</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/src/main/java/com/tongtech/ti/demo/security/security.wsdl</wsdl>
<extraargs>
<extraarg>-db</extraarg>
<extraarg>jaxb</extraarg>
<extraarg>-p</extraarg>
<extraarg>com.tongtech.ti.demo.security.service</extraarg>
<extraarg>-all</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
用maven先创建一个空的工程,如何创建,自己上上搜搜吧,主要是用maven的目录结构。
然后将上面的pom文件内容覆盖到创建好的pom文件中。
然后将wsdl文件复制保存到/src/main/java/com/tongtech/ti/demo/security/security.wsdl
然后命令行运行
mvn eclipse:eclipse或者mvn eclipse:myeclipse或者mvn idea:idea
然后maven会帮助你创建所需要的文件和类。
用eclipse或者idea打开工程,在创建好的目录下面创建com.tongtech.ti.demo.security.ut.client和com.tongtech.ti.demo.security.ut.server包,打开xxxx_xxxx_client.java文件,复制上面给的client.java文件,server同理,将client移动到client包下面,把server移动到server包下面,然后新建java类,起名叫UTPasswordClientCallBack.java和UTPasswordServerCallBack.java,将上面提到的两个callback代码,分别复制到这两个类中,然后运行服务器端和客户端查看效果。