示例用的是spring+CXF来配置webservice

首先是web.xml配置,将spring,CXF的配置文件加载进去,由于我客户端跟服务端在同一个工程里面,所以配置文件在一块。

    <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/classes/spring-cxf.xml,<!--服务端用到的配置-->
/WEB-INF/classes/spring-cxf-client.xml<!--客户端用到的配置文件-->
</param-value>
</context-param>
    <servlet>
<servlet-name>cxf-jeeek</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cxf-jeeek</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>

一、服务端

<1>CXF的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:/META-INF/cxf/cxf.xml" />
<import resource="classpath:/META-INF/cxf/cxf-servlet.xml" />
<import resource="classpath:/META-INF/cxf/cxf-extension-soap.xml" />
<!--配置拦截器,用来验证Token信息-->
<bean id="exampleServiceInterceptor" class="com.ekservice.interceptor.ExampleServiceInterceptor">
</bean> <bean id="exampleServiceImpl" class="com.ekservice.impl.ExampleServiceImpl" />
<jaxws:endpoint implementor="#exampleServiceImpl" address="/ExampleService">
<!-- -->
<jaxws:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<!-- 这个地方不知道为什么,官方文档说CXF2.0.x需要加这个过滤器,但是我用的是CXF2.7.7不加SAAJInInterceptor过滤器报错 -->
<bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
<bean id="WSS4JInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken"></entry>
<entry key="passwordType" value="PasswordText"></entry>
<!-- 设置密码类型为加密
<entry key="passwordType" value="PasswordDigest" />--> <entry key="passwordCallbackClass" value="com.ekservice.interceptor.ExampleServiceInterceptor"></entry>
</map>
</constructor-arg>
</bean>
</jaxws:inInterceptors> <jaxws:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
</jaxws:outInterceptors>
</jaxws:endpoint> </beans>

<2>拦截器ExampleServiceInterceptor.java的代码,有详细注释

package com.ekservice.interceptor;

import org.apache.log4j.Logger;
import org.apache.ws.security.WSPasswordCallback;
import org.apache.ws.security.WSSecurityException; import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map; /**
* @author EK
* @version 创建时间:2015-5-14 下午04:13:47
* 类说明
*/
public class ExampleServiceInterceptor implements CallbackHandler{
Logger logger = Logger.getLogger(ExampleServiceInterceptor.class); private Map<String, String> passwords = new HashMap<String, String>(); public ExampleServiceInterceptor() {
passwords.put("admin", "password");
}
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
String identifier = pc.getIdentifier();
int usage = pc.getUsage();
logger.info("Client Token [username: " + identifier+", password: "+ passwords.get(identifier) + "] Exist user: "+passwords.containsKey(identifier));
if (usage == WSPasswordCallback.USERNAME_TOKEN) {// 密钥方式USERNAME_TOKEN
if (!passwords.containsKey(identifier)) {
try {
throw new WSSecurityException("User not match - "+identifier);
} catch (WSSecurityException e) {
e.printStackTrace();
}
}
// username token pwd...
// ▲这里的值必须和客户端设的值相同,从cxf2.4.x后校验方式改为cxf内部实现校验,不必自己比较password是否相同
// 请参考:http://cxf.apache.org/docs/24-migration-guide.html的Runtime
// Changes片段
pc.setPassword(passwords.get(identifier));// ▲【这里非常重要】▲
// ▲PS 如果和客户端不同将抛出org.apache.ws.security.WSSecurityException:
// The
// security token could not be authenticated or
// authorized异常,服务端会认为客户端为非法调用
}else if (usage == WSPasswordCallback.SIGNATURE) {// 密钥方式SIGNATURE
if (!passwords.containsKey(identifier)) {
try {
throw new WSSecurityException("User not match - "+identifier);
} catch (WSSecurityException e) {
e.printStackTrace();
}
}
// set the password for client's keystore.keyPassword
// ▲这里的值必须和客户端设的值相同,从cxf2.4.x后校验方式改为cxf内部实现校验,不必自己比较password是否相同;
// 请参考:http://cxf.apache.org/docs/24-migration-guide.html的Runtime
// Changes片段
pc.setPassword(passwords.get(identifier));// //▲【这里非常重要】▲
// ▲PS:如果和客户端不同将抛出org.apache.ws.security.WSSecurityException:The
// security token could not be authenticated or
// authorized异常,服务端会认为客户端为非法调用
}
}
} }

<3>接口及其实现类的代码,比较简单,只是做个示例

package com.ekservice.service;

import com.ek.entry.user.User;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService; /**
* @author EK
* @version 创建时间:2015-5-14 下午02:17:59
* 类说明
*/
@WebService(targetNamespace="http://jeeek-dp/", name="ExampleService")
public interface ExampleService { @WebResult(name="password")
@WebMethod(action="http://jeeek-dp/ExampleService/getStr")
public User getStr(@WebParam(name="name")String userName); @WebMethod(action="http://jeeek-dp/ExampleService/receive")
public void receive(); @WebResult(name="tokenId")
@WebMethod(action="http://jeeek-dp/ExampleService/getTokenId")
public String getTokenId(); @WebResult(name="sendUnitInfo")
@WebMethod(action="http://jeeek-dp/ExampleService/getSendUnitInfo")
public int getSendUnitInfo(@WebParam(name="orgAccountId")long orgAccountId, @WebParam(name="recOrgType")int recOrgType, @WebParam(name="recOrgId")long recOrgId); }
package com.ekservice.impl;

import com.ek.entry.user.User;
import com.ekservice.service.ExampleService;
import org.apache.log4j.Logger; import javax.jws.WebService; /**
* @author EK
* @version 创建时间:2015-5-14 下午02:30:35
* 类说明
*/
@WebService(targetNamespace="http://jeeek-dp/", serviceName="ExampleService", name="ExampleService")
public class ExampleServiceImpl implements ExampleService {
Logger logger = Logger.getLogger(ExampleServiceImpl.class); public User getStr(String userName) {
User user = new User();
user.setAddress("北京市海淀区222号");
user.setMobilePhone("010-1101111"); System.out.println(userName+" "+user.getAddress()); return user;
} @Override
public void receive() {
this.logger.info("Call reveive() method....");
} @Override
public String getTokenId() {
this.logger.info("Call getTokenId() method....");
return "success";
} @Override
public int getSendUnitInfo(long orgAccountId, int recOrgType, long recOrgId) {
this.logger.info("Call getSendUnitInfo() method...."+orgAccountId+", "+recOrgType+", "+recOrgId);
return 0;
} }

二、客户端

<1>CXF配置文件,基本类似于服务端配置

<?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:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd"> <bean id="exampleServiceClientInterceptor"
class="com.ek.client.interceptor.ExampleServiceClientInterceptor"></bean>
<bean id="WSS4JOutInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="passwordType" value="PasswordText" />
<entry key="user" value="admin" />
<!-- <entry key="mustUnderstand" value="false"></entry> -->
<entry key="passwordCallbackRef">
<ref bean="exampleServiceClientInterceptor" />
</entry>
</map>
</constructor-arg>
</bean>
<jaxws:client id="exampleService"
address="http://localhost:8080/jeeek-dp/services/ExampleService"
serviceClass="com.ek.client.services.example.ExampleService">
<jaxws:outInterceptors>
<bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor"></bean>
<ref bean="WSS4JOutInterceptor"/>
</jaxws:outInterceptors>
</jaxws:client> <bean id="eperpServiceClientInterceptor"
class="com.ek.client.interceptor.CPERPServiceClientInterceptor"></bean>
<bean id="cperp" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="passwordType" value="PasswordText" />
<entry key="user" value="cpweb" />
<entry key="passwordCallbackRef">
<ref bean="eperpServiceClientInterceptor" />
</entry>
</map>
</constructor-arg>
</bean> </beans>

<2>客户端拦截器代码

package com.ek.client.interceptor;

import org.apache.log4j.Logger;
import org.apache.ws.security.WSPasswordCallback;
import org.apache.ws.security.WSSecurityException; import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map; /**
* @author EK
* @version 创建时间:2015年5月15日 上午11:36:20
* 类说明
*/
public class ExampleServiceClientInterceptor implements CallbackHandler{ Logger logger = Logger.getLogger(ExampleServiceClientInterceptor.class); private Map<String, String> passwords = new HashMap<String, String>(); public ExampleServiceClientInterceptor() {
passwords.put("admin", "password");
}
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
String identifier = pc.getIdentifier();
int usage = pc.getUsage(); if (usage == WSPasswordCallback.USERNAME_TOKEN) {// 密钥方式USERNAME_TOKEN
logger.info("Client Token [username: " + identifier+", password: "+ passwords.get(identifier) + "] Exist user= "+passwords.containsKey(identifier));
if (!passwords.containsKey(identifier)) {
try {
throw new WSSecurityException("User not match - "+identifier);
} catch (WSSecurityException e) {
e.printStackTrace();
}
}
pc.setPassword(passwords.get(identifier));// //▲【这里非常重要】▲
}else if (usage == WSPasswordCallback.SIGNATURE) {// 密钥方式SIGNATURE
if (!passwords.containsKey(identifier)) {
try {
throw new WSSecurityException("User not match - "+identifier);
} catch (WSSecurityException e) {
e.printStackTrace();
}
}
pc.setPassword(passwords.get(identifier));// //▲【这里非常重要】▲
}
}
} }

<3>客户端接口代码

package com.ek.client.services.example;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper; /**
*
*/
@WebService(targetNamespace = "http://jeeek-dp/", name = "ExampleService")
public interface ExampleService { @WebResult(name = "password", targetNamespace = "")
@RequestWrapper(localName = "getStr", targetNamespace = "http://jeeek-dp/")
@WebMethod(action = "http://jeeek-dp/ExampleService/getStr")
@ResponseWrapper(localName = "getStrResponse", targetNamespace = "http://jeeek-dp/")
public User getStr(
@WebParam(name = "name", targetNamespace = "")
java.lang.String name
); @RequestWrapper(localName = "receive", targetNamespace = "http://jeeek-dp/")
@WebMethod(action = "http://jeeek-dp/ExampleService/receive")
public void receive(); @WebResult(name = "tokenId", targetNamespace = "")
@RequestWrapper(localName = "getTokenId", targetNamespace = "http://jeeek-dp/")
@WebMethod(action = "http://jeeek-dp/ExampleService/getTokenId")
@ResponseWrapper(localName = "getTokenIdResponse", targetNamespace = "http://jeeek-dp/")
public java.lang.String getTokenId(); @WebResult(name = "sendUnitInfo", targetNamespace = "")
@RequestWrapper(localName = "getSendUnitInfo", targetNamespace = "http://jeeek-dp/")
@WebMethod(action = "http://jeeek-dp/ExampleService/getSendUnitInfo")
@ResponseWrapper(localName = "getSendUnitInfoResponse", targetNamespace = "http://jeeek-dp/")
public java.lang.Integer getSendUnitInfo(
@WebParam(name = "orgAccountId", targetNamespace = "")
java.lang.Long orgAccountId,
@WebParam(name = "recOrgType", targetNamespace = "")
java.lang.Integer recOrgType,
@WebParam(name = "recOrgId", targetNamespace = "")
java.lang.Long recOrgId
); }

<4>客户端调用类

package com.ek.client.call;

import com.ek.client.interceptor.ExampleServiceClientInterceptor;
import com.ek.client.services.example.ExampleService;
import com.ek.client.services.example.User;
import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.handler.WSHandlerConstants; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; /**
* @author EK
* @version 创建时间:2015年5月15日 上午11:05:06
* 类说明
*/
public class ExampleServiceClient { public static void main(String[] args) {
// ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring-cxf-client.xml");
// ExampleService es = (ExampleService) ctx.getBean("exampleService");
Map<String, Object> map = new HashMap<String, Object>();
map.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
map.put(WSHandlerConstants.USER, "admin");
map.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
map.put(WSHandlerConstants.PW_CALLBACK_CLASS, ExampleServiceClientInterceptor.class.getName()); List list = new ArrayList();
list.add(new SAAJOutInterceptor());
list.add(new WSS4JOutInterceptor(map)); JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(ExampleService.class);
factory.setAddress("http://localhost:8080/jeeek-dp/services/ExampleService");
factory.getOutInterceptors().addAll(list);
ExampleService es = (ExampleService) factory.create(); User u = es.getStr("ssss");
//Integer sui = es.getSendUnitInfo(1L, 2, 3L);
String tokenId = es.getTokenId();
//es.receive(); System.out.println("的, " + tokenId);
//System.out.println("的" + sui);
}
}

带有WS-Security验证的webservice的更多相关文章

  1. c# winform访问 带有windows身份验证的webservice

    1 将webservice设置为windows身份验证iis10中,要确认已安装windows身份验证在 控制面板 - >打开或关闭Windows功能 - >万维网服务 - >安全性 ...

  2. WS Security 认证方式详解

    本文参考文档如下: MSDN 官方详解 : http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/HowASP.NET ...

  3. c#调用带有安全认证的java webservice

    最近使用c#调用另外一个同事写的java webservice耽误了很多时间,网上资料不太完整,走了很多弯路,希望对大家有帮助. 基本思路是1.拼装soap使用http post ,主要将验证身份信息 ...

  4. Spring Security验证流程剖析及自定义验证方法

    Spring Security的本质 Spring Security本质上是一连串的Filter, 然后又以一个独立的Filter的形式插入到Filter Chain里,其名为FilterChainP ...

  5. .Net调用Java带验证的WebService解决方法

    最近遇到了一个问题,需要通过验证用户名.密码去调用对方Java给出的WebService接口. 搜索了很多资料,没想到最终很简单就完了.... (捂脸 第一步:添加web引用 第二步:进行验证,并完成 ...

  6. 使用SoapUI测试windows身份验证的webservice

    有个朋友问到用soapui测试wcf服务时如果使用windows身份验证要怎么传输凭据,于是自己试了一下.其实服务端是wcf还是webservice还是webapi都无所谓,关键是windows身份验 ...

  7. CXF生成本地ws调用代码测试webservice

    package com.free.webservice.client; import java.util.List; import cn.com.webxml.*; public class Weat ...

  8. Spring Security验证,提示正确的信息

    关于Spring Security的使用,之前也整理过一些笔记,但是在提示信息的时候,总感觉还缺点什么?不管是不是前后端分离,我们都希望在登录验证出现错误的时候,能够提示友好的中文信息. 在前后端不分 ...

  9. iOS 开发之路(登陆验证调用WebService)二

    swift3.0下使用Alamofire调用Webservice遇到的一些问题以及解决方案. 首先是针对没有证书的https下的接口处理问题(ps:不推荐在正式版本中使用),manager.reque ...

随机推荐

  1. java执行程序的内存分析系列专栏

    近段时间研究了java的程序执行过程中的内存分配,收获颇多,解决了我最近时间学习java的很多困惑点.写java内存分析系列的目的主要有两个,一来是希望给像我一样的java初学者一定的启发,希望也能解 ...

  2. PHP中几个输出函数echo,print(),print_r(),sprintf(),var_dump()的区别

    1:echo:是语句不是函数,没有返回值,可输出多个变量值,不需要圆括号.不能输出数组和对象,只能打印简单类型(如int,string). 2:print:是语句不是函数,有返回值 1 ,只能输出一个 ...

  3. Kafka 源代码分析之FileMessageSet

    这里主要分析FileMessageSet类 这个类主要是管理log消息的内存对象和文件对象的类.源代码文件在log目录下.这个类被LogSegment类代理调用用来管理分片. 下面是完整代码.代码比较 ...

  4. css清除浮动float

    css清除浮动float 1.分析HTML代码 <div class="outer"> <div class="div1">1</ ...

  5. Lambda(Linq)

    在谈到lambda表达式之前,首先要说一下委托,在下一章会详细介绍委托,在这里就是简单说明一下. 委托的关键字段delegate,声明委托 public delegate void NoReturnN ...

  6. JVM总结之内存区域

    Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,有的区域是线程共享的,有的区域是线程隔离的.如下图: 程序计数器 程序计数器(Progra ...

  7. Ionic 2+ 安卓环境搭建

    安装 安卓studio https://developer.android.com/studio/index.html 设置一个环境变量 _JAVA_OPTIONS:-Xmx512M 添加androi ...

  8. H5 data-*容易忽略的问题

    H5添加了data-*属性,非常方便 但经常忽略小写的问题, H5要求属性名全部小写,驼峰式命名的习惯掉坑了 测试代码如下: <html> <head> <script ...

  9. 基于Dapper的分页实现,支持筛选,排序,结果集总数,非存储过程

    简介 之前事先搜索了下博客园上关于Dapper分页的实现,有是有,但要么是基于存储过程,要么支持分页,而不支持排序,或者搜索条件不是那么容易维护. 代码 首先先上代码: https://github. ...

  10. CSS使用心得小结

    CSS心得 最近对CSS的使用有一些小心得,在此写下来给大家分享分享 .最后附上选择器的实例代码. ------DanlV CSS是什么 层叠样式表(英文全称:Cascading Style Shee ...