cxf拦截器

本文介绍了如何使用Apache CXF的拦截器实现Web Service的安全认证。在服务端,创建了一个拦截器,检查客户端发送的SOAP消息中的用户名和密码,只有当用户名为'wl'且密码为'1985310'时才允许调用。在客户端,创建了另一个拦截器,在发送SOAP消息前将用户名和密码添加到消息头部。通过这种方式,实现了客户端和服务器之间的安全交互。
摘要由CSDN通过智能技术生成

一 编写服务端

1 编写接口,在接口上面有@webService注解,表示该类是webService,接口里面方法注解为@webMethod,表示该方法是webService的方法

 



2 编写接口的实现类



3 编写拦截器,继承AbstractPhaseInterceptor类,实现handleMessage方法,在该方法里面实现拦截器的业务逻辑,在这里我实现的是如果客户端sopa消息传递用户名是wl,密码是1985310就是认证通过的客户端,可以继续向下执行,否则抛出异常,Phase这个类有很多常量,表示在服务器端的各个阶段拦截。

package com.atguigu.day01_ws.ws.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.Node;
import org.w3c.dom.NodeList;
//PhaseInterceptor 可以指定拦截器在哪个阶段起作用
public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

public AuthInterceptor() {
super(Phase.PRE_INVOKE);//调用之前拦截soap消息
 
}

@Override
public void handleMessage(SoapMessage msg) throws Fault {
  System.out.println("服务端拦截器="+msg);
   List<Header>headers= msg.getHeaders();
if(  headers==null||headers.size()<=0){
throw  new Fault(new IllegalArgumentException("没有header 不能调用"));
}

Header firstHeader=headers.get(0);
Element ele=(Element)firstHeader.getObject();
NodeList  userIds= ele.getElementsByTagName("userId");
NodeList  passwards= ele.getElementsByTagName("password");
 
System.out.println("用户名个数="+userIds.getLength());
System.out.println("密码个数="+passwards.getLength());
if(userIds.getLength()!=1 || passwards.getLength()!=1 ){
throw  new Fault(new IllegalArgumentException("格式不对"));
}
String userId= userIds.item(0).getTextContent();
String passward= passwards.item(0).getTextContent();
System.out.println("用户名="+userId);
System.out.println("密码="+passward);
if(!"wl".equals(userId)||!"1985310".equals(passward) ){
throw  new Fault(new IllegalArgumentException("用户名或者密码不对"));
}

}


 
}


 



4 运行服务端,并设置该拦截器 

           设置服务器端入拦截器

   List<Interceptor<? extends Message>>  inInterceptors =endpointImpl.getInInterceptors();
   inInterceptors.add(new AuthInterceptor());





二 编写客户端

1 根据wsdl 生成客户端代码,左边是生成的客户端代码



2 编写客户端拦截器,在发送soap消息之前,把用户名和密码塞到soap消息的头部,在准备发送soap消息的时候进行拦截

package com.atguigu.day01_ws.ws.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;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
//PhaseInterceptor 可以指定拦截器在哪个阶段起作用
public class AddHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

private String userId;
private String password;


public AddHeaderInterceptor(String userId,String password) {
super(Phase.PREPARE_SEND);//准备发送soap消息的时候
this.userId=userId;
this.password=password;
}


 


@Override
public void handleMessage(SoapMessage msg) throws Fault {
  System.out.println("客户端拦截器"+msg);
   List<Header>headers= msg.getHeaders();
   
  Document doc=DOMUtils.createDocument();
  Element ele=doc.createElement("authHeader");
 
  Element idEle=doc.createElement("userId");
  idEle.setTextContent(userId);
Element passwordEle=doc.createElement("password");
passwordEle.setTextContent(password);

ele.appendChild(idEle);
ele.appendChild(passwordEle);
headers.add(new Header( new QName("www.xxx") ,ele));
}


 




public String getUserId() {
return userId;
}








public void setUserId(String userId) {
this.userId = userId;
}








public String getPassword() {
return password;
}








public void setPassword(String password) {
this.password = password;
}




}





3 运行客户端,并设置出拦截器




运行结果


服务端打印出用户名和密码信息,证明客户端传递了用户名和密码



客户端打印出消息 




用tcp监控得到客户端传递的消息,确实是传递了用户名和密码




cxf的拦截器成功。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值