CXF 使用 UserName Token进行验证

网络当中搜索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代码,分别复制到这两个类中,然后运行服务器端和客户端查看效果。

你可能感兴趣的:(java,apache,eclipse,maven,Security)