参照上一篇博文 基于HTTPS的webservice 的环境搭建step by step
完成所需环境之后,就可以开始接下来的著名项目HelloWorld了。
1. 建立一个helloworld的web项目
2. 创建SEI
package com.harvey.services;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
@WebService(targetNamespace="http://webservice.harvey.com")
public interface HelloWorldInf {
public String sayHello(@WebParam(name="name")String name);
}
通过@WebService注解将该接口声明为webservice
3. 创建SIB
package com.harvey.services;
import javax.jws.WebService;
@WebService(endpointInterface="com.harvey.services.HelloWorldInf",
targetNamespace="http://webservice.harvey.com")
public class HelloWorldImpl implements HelloWorldInf {
public String sayHello(String name) {
return "hello,"+name;
}
}
这个类功能虽然很强大,但是应该比较容易看懂,就是向调用者打招呼。
4. 建立鉴权的handler
package com.harvey.services;
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 ServerPasswordCallback implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
String pw = pc.getPassword();
String idf = pc.getIdentifier();
if (!"harvey".equals(idf) || !"123456".equals(pw)) {
throw new SecurityException("鉴权失败!");
}
}
}
5. 通过spring整合
通过spring发布helloworld服务并为服务添加鉴权的handler.
在web.xml的配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</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>/services/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
为了方便直接在src目录下建立applicationContext.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="hello" class="com.harvey.services.HelloWorldImpl" />
<jaxws:endpoint id="helloworldservice"
endpointName="e:helloWorldPointName"
serviceName="s:helloworldservice"
implementor="#hello"
address="/helloworld"
xmlns:e="http://webservice.harvey.com/endponit"
xmlns:s="http://webservice.harvey.com/service">
<jaxws:inInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="passwordType"
value="PasswordText" />
<entry key="user" value="cxfServer" />
<entry key="passwordCallbackRef">
<ref bean="serverPasswordCallback" />
</entry>
</map>
</constructor-arg>
</bean>
</jaxws:inInterceptors>
</jaxws:endpoint>
<bean id="serverPasswordCallback" class="com.harvey.services.ServerPasswordCallback" />
</beans>
Server端的工作就这些了,结合我们在上一篇文章中提到的数字证书的环境,一个支持数字证书和鉴权的server端搭建完成了。
接下来我们在转到client端,看一下如何在client加入对数字证书以及鉴权的支持。
6. 创建client端的密码的handler
为了方便起见,我们不再为client独立创建功能,与service在同一项目下建立client端的回调类,为webservice的请求添加鉴权的头信息
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 ClientPasswordCallback implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
pc.setPassword("123456");
pc.setIdentifier("Harvey");
}
}
7. 创建client的spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xmlns:sec="http://cxf.apache.org/configuration/security"
xsi:schemaLocation="
http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="client" class="com.harvey.services.HelloWorldInf"
factory-bean="clientFactory" factory-method="create" />
<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="com.harvey.services.HelloWorldInf" />
<property name="address" value="https://localhost:8443/WebServiceDemo/services/helloworld" />
<property name="outInterceptors">
<list>
<ref bean="wss4jOut" />
</list>
</property>
</bean>
<bean id="wss4jOut" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="user" value="cxfClient" />
<entry key="passwordType" value="PasswordText" />
<entry key="passwordCallbackClass" value="com.harvey.services.ClientPasswordCallback" />
</map>
</constructor-arg>
</bean>
</beans>
8. 创建client端的测试类,并将上一篇 博文中生成的client.jks和truststore.jks添加到类目录下
package com.harvey.test;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.harvey.services.HelloWorldInf;
public class HelloWorldClient {
private final static String trustStore = "truststore.jks";
private final static String keyStore = "client.jks";
private final static String trustStorePass = "123456";
private final static String keyStorePass = "999999";
/**
* @param args
*/
public static void main(String[] args) throws Exception{
ApplicationContext context=new ClassPathXmlApplicationContext("client-bean.xml");
HelloWorldInf client = (HelloWorldInf)context.getBean("client");
Client proxy = ClientProxy.getClient(client);
HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
TLSClientParameters tlsParams = conduit.getTlsClientParameters();
if (tlsParams == null) {
tlsParams = new TLSClientParameters();
}
tlsParams.setSecureSocketProtocol("SSL");
tlsParams.setKeyManagers(getKeyManagers());
tlsParams.setTrustManagers(getTrustManagers());
conduit.setTlsClientParameters(tlsParams);
String response = client.sayHello("han");
System.out.println(response);
}
private static TrustManager[] getTrustManagers() throws IOException {
try {
String alg = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory factory = TrustManagerFactory.getInstance(alg);
InputStream fp = HelloWorldClient.class.getResourceAsStream(trustStore);
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(fp, trustStorePass.toCharArray());
fp.close();
factory.init(ks);
TrustManager[] tms = factory.getTrustManagers();
return tms;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
}
return null;
}
private static KeyManager[] getKeyManagers() throws IOException {
try {
String alg = KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory factory = KeyManagerFactory.getInstance(alg);
InputStream fp = HelloWorldClient.class.getResourceAsStream(keyStore);
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(fp, keyStorePass.toCharArray());
fp.close();
factory.init(ks, keyStorePass.toCharArray());
KeyManager[] keyms = factory.getKeyManagers();
return keyms;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
}
return null;
}
}
9.现在就可以运行client端测试鉴权功能了。
本来想着认真解释一下代码,不过环境太吵,实在没法安静下来写,就算是抛砖引玉吧。
分享到:
相关推荐
现在主流的webService框架,一个是axis2,一个是cxf,本资源是基于cxf框架的简单例子
CXF webService 工具类
使用jdk1.6、cxf2.3和tomcat开发的一个关于验证码的webservice接口,主要实现对手机验证码的验证。
CXF webservice,mybatis持久层框架,增删改查实例;完整jar包;
cxf WebService jar包
Web Service学习-CXF开发Web Service的权限控制(二)
maven项目 cxf webservice mongodb mysql 公司真实现目初期实现
实战Web+Service+with+CXF webservice快速入门 webservice快速入门
mybatis+spring+cxf webservice服务 项目框架代码例子,绝对是可以参考的,信不信,只有下载之后才知道
使用CXF技术发布webservice,以及客户端的调用方法(可直接复制使用),基于soap12
基于CXF实现WebService开发.pdf
基于spring注解的cxf实现webservice
CXF WebService整合Spring代码(包含服务,客户端两个工程 和 文档) 需要视频的话,留邮箱
使用cxf webservice时容易出现的异常
使用 CXF 做 webservice 简单例子,用的是cxf-2.1.3.jar
SSH整合cxf webservice实例
一、CXF WebService准备工作 二、CXF 入门示例 三、CXF对Interceptor拦截器的支持 四、CXF WebService中传递复杂类型对象 五、CXF整合Spring
cxf WebService jar包
基于CXF的WebService服务端和客户端示例,CXF+Spring,希望能为WebService开发者提供帮助。WebService,CXF,Spring.
2.用cxf开发webservice 3.这个服务端和客户端的小demo 在服务端 对外开放接口服务,然后在客户端 调用服务端的方法, 实现客户端(一个javaweb项目)对服务端(javaweb项目)方法的调用, 实际上就是发送和接收消息...