CXF 使用 UserName Token进行验证

本文提供了一个使用CXF框架实现Web服务安全性的示例,包括客户端和服务端代码及配置,通过WSS4J拦截器实现基于用户名令牌的安全验证。
网络当中搜索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代码,分别复制到这两个类中,然后运行服务器端和客户端查看效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值