Web Service怎样进行权限控制?

解决思路:server端要求input消息总是携带实username。password信息,假设没实username和password信息。直接拒绝调用

解决方式:拦截器

为了让程序猿能訪问,并改动CXF框架所生成的SOAP消息,CXF提供了拦截器

CXF(Celtix +XFire)说明:

假设不用CXF等框架,SOAP消息的生成。解析都是由程序猿负责。不管是加入username。password信息还是提取username,password信息,都可由程序猿代码完毕。

假设使用CXF等框架,SOAP消息的生成,解析都是由CXF等框架来完毕。

总的来说,CXF对公布WebService进行了封装,简化了我们的操作。

拦截器:

服务端加入拦截器:

1,获取Endpoint的publish的方法返回值。

2,调用该对象的getInInterceptors,getOutInterceptors方法来获取In。Out拦截器列表,接下来就能够加入拦截器了

package com.tgb.client;

import javax.xml.ws.Endpoint;

import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.EndpointImpl; import com.tgb.service.HelloWorld;
import com.tgb.service.impl.HelloWorldImpl; public class ServerMain { public static void main(String[] args){ HelloWorld hw=new HelloWorldImpl();
//调用endpoint的publish方法。来公布web service
// Endpoint.publish("http://192.168.24.215:8889/hjy",hw);
EndpointImpl ep=(EndpointImpl)Endpoint.publish("http://192.168.24.215:8899/hjy",hw); //加入In拦截器
ep.getInInterceptors().add(new LoggingInInterceptor());
//加入Out拦截器
ep.getOutInterceptors().add(new LoggingOutInterceptor()); System.out.println("Web Service暴露成功");
}
}

输出内容:


客户端加入拦截器:

1,加入对应的CXF的jar包

2,调用ClientProxy的getClient方法,调用该方法以远程Web Service的代理为參数

3,调用Client对象的getInInterceptors。getOutInterceptors方法来获取In。Out拦截器列表,接下来就能够加入拦截器了

package hjy;

import java.util.List;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor; import com.tgb.service.Cat;
import com.tgb.service.HelloWorld;
import com.tgb.service.User;
import com.tgb.service.impl.HelloWorldImpl; public class ClientMain { public static void main(String[] args){
HelloWorldImpl factory=new HelloWorldImpl();
//此处返回的仅仅是远程Web Service的代理
HelloWorld hw=factory.getHelloWorldImplPort(); Client client=ClientProxy.getClient(hw);
client.getInInterceptors().add(new LoggingInInterceptor());
client.getOutInterceptors().add(new LoggingOutInterceptor()); System.out.println(hw.sayHi("hejingyuan")); System.out.println("--------------------------"); User user=new User();
user.setId(20);
user.setName("孙悟空");
user.setPass("111");
user.setAddress("花果山"); List<Cat> cats=hw.getCatsByUser(user);
for(Cat cat:cats){
System.out.println(cat.getName());
} System.out.println("--------------------------"); System.out.println(hw.getAllCats().getEntry().get(0).getKey());
System.out.println(hw.getAllCats().getEntry().get(0).getValue().getName()); }
}

打印内容为:


自己定义拦截器

实现效果:当输入usernamepassword时。才干够调用我们的服务。

即我们须要在服务端加入输入拦截,在客户端加入输出拦截

自己定义拦截器,须要实现Interceptor接口,实际上,我们通常会继承AbstractPhaseInterceptor

服务端代码:

package com.tgb.client;

import javax.xml.ws.Endpoint;

import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.EndpointImpl; import com.tgb.auth.AuthInterceptor;
import com.tgb.service.HelloWorld;
import com.tgb.service.impl.HelloWorldImpl; public class ServerMain { public static void main(String[] args){ HelloWorld hw=new HelloWorldImpl();
//调用endpoint的publish方法,来公布web service
// Endpoint.publish("http://192.168.24.215:8889/hjy",hw);
EndpointImpl ep=(EndpointImpl)Endpoint.publish("http://192.168.24.215:8891/hjy",hw); //加入In拦截器,该AuthInterceptor就会负责检查username。password是否正确
ep.getInInterceptors().add(new AuthInterceptor());
//加入Out拦截器
// ep.getOutInterceptors().add(new LoggingOutInterceptor()); System.out.println("Web Service暴露成功");
}
}

AuthInterceptor :

package com.tgb.auth;

import java.util.List;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList; //通过PhaseInterceptor,能够指定拦截器在哪个阶段起作用
public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage>{ //因为AbstractPhaseInterceptor无无參数构造器,使用继承的方式,须要显示调用父类有參数的构造器
public AuthInterceptor(){
//super表示显示调用父类有參数的构造器
//显示调用父类构造器之后,程序将不会隐式调用父类无參数的构造器
super(Phase.PRE_INVOKE);//该拦截器将会调用之前拦截SOAP消息
}
//实现自己的拦截器时。须要实现handleMessage方法。
//handleMessage方法中的形參就是被拦截到的Soap消息
//一旦程序获取了SOAP消息,剩下的事情就能够解析SOAP消息或改动SOAP消息
@Override
public void handleMessage(SoapMessage msg) throws Fault { System.out.println("-------"+msg);
//从这里能够看出,我们已经拦截到了SOAP消息 //得到SOAP消息全部Header
List<Header> headers=msg.getHeaders(); //假设没有Header
if(headers==null||headers.size()<1){
throw new Fault(new IllegalArgumentException("根本没有Header,不能调用"));
} //假如要求第一个Header携带了username,password信息
Header firstHeader=headers.get(0);
Element ele=(Element)firstHeader.getObject(); NodeList userIds=ele.getElementsByTagName("userId");
NodeList userPasses=ele.getElementsByTagName("userPass"); if(userIds.getLength()!=1){
throw new Fault(new IllegalArgumentException("username的格式不对。"));
}
if(userPasses.getLength()!=1){
throw new Fault(new IllegalArgumentException("password的格式不对!"));
} //得到第一个userId元素里的文本内容。以该内容作为username字
String userId=userIds.item(0).getTextContent();
String userPass=userPasses.item(0).getTextContent();
//实际项目中。应该去查询数据库,该usernamepassword是否被授权调用web service
if(!userId.equals("hejingyuan") || !userPass.equals("hjy")){
throw new Fault(new IllegalArgumentException("usernamepassword不对!"));
}
} }

客户端代码:

package hjy;

import java.util.List;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy; import com.tgb.auth.AddHeaderInterceptor;
import com.tgb.service.Cat;
import com.tgb.service.HelloWorld;
import com.tgb.service.User;
import com.tgb.service.impl.HelloWorldImpl; public class ClientMain { public static void main(String[] args){
HelloWorldImpl factory=new HelloWorldImpl();
//此处返回的仅仅是远程Web Service的代理
HelloWorld hw=factory.getHelloWorldImplPort(); Client client=ClientProxy.getClient(hw);
//參数为输入的username。password
client.getOutInterceptors().add(new AddHeaderInterceptor("hejingyuan","hjy")); System.out.println(hw.sayHi("hejingyuan")); System.out.println("--------------------------"); User user=new User();
user.setId(20);
user.setName("孙悟空");
user.setPass("111");
user.setAddress("花果山"); List<Cat> cats=hw.getCatsByUser(user);
for(Cat cat:cats){
System.out.println(cat.getName());
} System.out.println("--------------------------"); System.out.println(hw.getAllCats().getEntry().get(0).getKey());
System.out.println(hw.getAllCats().getEntry().get(0).getValue().getName()); }
}

AddHeaderInterceptor:

package com.tgb.auth;

import java.util.List;

import javax.xml.namespace.QName;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Document;
import org.w3c.dom.Element; public class AddHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage>{ private String userId;
private String userPass; public AddHeaderInterceptor(String userId,String userPass){
super(Phase.PREPARE_SEND);//在准备发送SOAP消息时启用该拦截器
this.userId=userId;
this.userPass=userPass;
}
@Override
public void handleMessage(SoapMessage msg) throws Fault {
List<Header> headers=msg.getHeaders();
//创建Document对象
Document doc=DOMUtils.createDocument();
Element ele=doc.createElement("authHeader"); //此处创建的元素应该依照server那边的要求
Element idEle=doc.createElement("userId");
idEle.setTextContent(userId);
Element passEle=doc.createElement("userPass");
passEle.setTextContent(userPass); ele.appendChild(idEle);
ele.appendChild(passEle); /**
* 上面代码生成了一个例如以下XML文档片段
* <authHeader>
* <userId>hejingyuan</userId>
* <userPass>hjy</userPass>
* </authHeader>
*/
//把ele元素包装成Header,并加入到SOAP消息的Header列表中
headers.add(new Header(new QName("hejingyuan"),ele));
} }

启动服务端的ServerMain的main函数。将服务公布。然后启动客户端ClientMain的main函数去訪问服务端提供的服务。

usernamepassword错误时:

usernamepassword正确时:

总结:

权限控制的实现方式为使用拦截器。对于拦截到的Soap消息进行改动。

SOAP消息:

根元素是Envolope

Header

默认情况下。Header元素不是强制出现的

Header元素由程序猿控制加入,主要用户携带一些额外的信息。比方username,password信息

Body

假设调用正确,Body元素的内容应该遵守WSDL所要求的格式

假设调用错误。Body元素的内容就是Fault子元素

源代码下载

Web Service学习-CXF开发Web Service的权限控制(二)的更多相关文章

  1. Web Service学习-CXF开发Web Service实例demo(一)

    Web Service是什么? Web Service不是框架.更甚至不是一种技术. 而是一种跨平台,跨语言的规范 Web Service解决什么问题: 为了解决不同平台,不同语言所编写的应用之间怎样 ...

  2. 使用CXF开发Web Service服务

    1.使用CXF开发Web Service服务端 1.1 开发一个Web Service业务接口,该接口要用@WebService修饰 (1)创建一个Java项目MyServer (2)在MyServe ...

  3. web前端学习python之第一章_基础语法(二)

    web前端学习python之第一章_基础语法(二) 前言:最近新做了一个管理系统,前端已经基本完成, 但是后端人手不足没人给我写接口,自力更生丰衣足食, 所以决定自学python自己给自己写接口哈哈哈 ...

  4. Web Service学习之一:Web Service原理

    一.定义 Web Service 不是框架也不是技术 而是解决远程调用.跨平台调用.跨语言调用问题的一种规范. 二.应用1.同一个公司新.旧系统的整合:比如CRM系统与OA.客服系统相互调用2.不同公 ...

  5. Linux学习总结(14)——Linux权限控制

    linux中,权限的学习是必不可少的,不论是作为一名运维工程师或者是单一的管理者,学习好linux中的权限控制,你就可以保护好自己的隐私同时规划好你所管理的一切. 权限的学习是很多的,不要认为自己已经 ...

  6. CTFHub Web题学习笔记(Web前置技能+信息泄露题解writeup)

    今天CTFHub正式上线了,https://www.ctfhub.com/#/index,之前有看到这个平台,不过没在上面做题,技能树还是很新颖的,不足的是有的方向的题目还没有题目,CTF比赛时间显示 ...

  7. 学习andriod开发之 异步加载图片(二)--- 使用其他进度条

    大家好 我是akira上一节 我们讲到使用AsyncTask 这个类进行异步的下载 主要是涉及到一些图片的更新 这次我们继续上一个demo的改进 . 不知道你是否发现一个问题 上一节我们遗留了两个bu ...

  8. linux —— 学习笔记(用户管理与权限控制)

    目录:1.用户的创建和管理    2.组的创建和管理 3.文件执行权限的控制 4.不用密码执行sudo 1.用户的创建和管理 用户的创建和管理: useradd.usermod . userdel . ...

  9. Apache CXF实现Web Service(5)—— GZIP使用

    Apache CXF实现Web Service(5)-- GZIP使用 参考来源: CXF WebService整合Spring Apache CXF实现Web Service(1)--不借助重量级W ...

随机推荐

  1. 【洛谷2839/BZOJ2653】middle(主席树)

    题目: 洛谷2839 分析: 记\(s_i\)表示原序列中第\(i\)大的数. 考虑对于任意一个区间\([a,b]\),设它的中位数为\(s_m\),那么这个区间内大于等于\(s_m\)的数和小于\( ...

  2. PHP网站 通过js方式判断是否是手机访问,若是 跳转到手机版网址!

    <script type="text/javascript" src="http://i3.dukuai.com/ui/js/jquery-1.32pack.js& ...

  3. Boost Bimap示例

    #include <string> #include <iostream> #include <boost/bimap.hpp> template< clas ...

  4. android黑科技系列——自动注入代码工具icodetools

    一.前言 在前面已经介绍完了 自动给apk中注入日志代码工具icodetools原理了,在那里我们曾经说过其实离真正的可使用价值有点距离,本篇就对这个工具进行一些优化,让其真正意义上开始能工作量产.当 ...

  5. 【译】x86程序员手册09-第3章程序指令集

    注:觉得本章内容与理解操作系统不直接相关,所以本章并未看完,也就没有翻译完,放在这里中是为了保证手册的完整.有兴趣的人可以去原址查看. https://pdos.csail.mit.edu/6.828 ...

  6. CSS3 background-origin 属性

    CSS3 background-origin 属性 padding-box 背景图像相对于内边距框来定位. border-box 背景图像相对于边框盒来定位. content-box 背景图像相对于内 ...

  7. 【Caffe】Ubuntu16.04上配置安装caffe(Only CPU)

    一.首先看看自己的系统,Ubuntu16.04,cpu,没有Nvidia,没有opencv 二.安装依赖包 安装protobuf,leveldb,snappy,OpenCV,hdf5, protobu ...

  8. -moz、-ms、-webkit

    1.-moz代表firefox浏览器私有属性 2.-ms代表IE浏览器私有属性 3.-webkit代表safari.chrome私有属性 需要设置这个的样式: transform,border-rad ...

  9. CAD在图纸保存的同时,也把基本信息保存了(网页版)

    主要用到函数说明: MxDrawXCustomFunction::Mx_SaveDwgToURLEx 保存DWG文件到服务器上的扩展函数.详细说明如下: 参数 说明 pszServerUrl 服务器网 ...

  10. Ansible 利用playbook批量部署mariadb

    环境说一下 192.168.30.21     ansible 192.168.30.25     client1 192.168.30.26     client2 这里我的ansible环境已经部 ...