加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

WebService(7)_Apache CXF拦截器-权限管理-登录验证

发布时间:2020-12-16 21:54:36 所属栏目:安全 来源:网络整理
导读:上一篇提到过CXF的安全性问题.. 这里提供一个解决思路,在调用CXF服务端的时候,进行用户校验.这样子似乎能提高一些安全.. 正式项目使用的话,用户名和密码都要MD5加密..? 不过使用用户名和密码,还是有一点 "伪安全"的意思..? 别人要是抓个包... 不全部歇菜嘛..

上一篇提到过CXF的安全性问题..

这里提供一个解决思路,在调用CXF服务端的时候,进行用户校验.这样子似乎能提高一些安全..

正式项目使用的话,用户名和密码都要MD5加密..?

不过使用用户名和密码,还是有一点 "伪安全"的意思..?

别人要是抓个包... 不全部歇菜嘛..

不废话了.. 先把工程代码贴上来.. 下载之后可以直接运行.

CXF-拦截器-权限控制-登录校验


服务端接口

package com.cxf.inter;

import javax.jws.WebService;

@WebService
public interface CXFInterface {
	
	public String sayHello(String name);
	
}


接口实现类

package com.cxf.inter;

import javax.jws.WebService;

@WebService
public class CXFDemoImpl implements CXFInterface {

	@Override
	public String sayHello(String name) {
		return "Interceptor Hello : " + name;
	}

}


服务端拦截器

package com.cxf;

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;

public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

	// 在拦截器调用方法之前,拦截SOAP消息.
	public AuthInterceptor() {
		super(Phase.PRE_INVOKE);
	}

	@Override
	/**
	 * 拦截器处理方法
	 */
	public void handleMessage(SoapMessage message) throws Fault {
		System.out.println("---- 进入拦截器 ----");

		// 获取SOAP携带的所有Header
		List<Header> headers = message.getHeaders();
		if (null == headers || headers.size() < 1)
			throw new Fault(new IllegalArgumentException("拦截器实施拦截,没有Header"));

		// 获取Header携带的用户名和密码
		Header firstHeader = headers.get(0);
		Element element = (Element) firstHeader.getObject();

		NodeList userNameElement = element.getElementsByTagName("userName");
		NodeList passWordElement = element.getElementsByTagName("passWord");

		if (userNameElement.getLength() != 1)
			throw new Fault(new IllegalArgumentException("用户名不能为空.."));
		if (passWordElement.getLength() != 1)
			throw new Fault(new IllegalArgumentException("密码不能为空.."));

		// 获取元素中的文本内容
		String username = userNameElement.item(0).getTextContent();
		String password = passWordElement.item(0).getTextContent();

		// 实际项目中,是从数据库中取数据做校验
		if (!username.equals("cyx") || !password.equals("123456")) {
			throw new Fault(new IllegalArgumentException("用户名或密码不正确.."));
		} else {
			System.out.println("验证成功!!");
		}

	}

}

服务端发布主类

package com.cxf;

import javax.xml.ws.Endpoint;

import org.apache.cxf.jaxws.EndpointImpl;

import com.cxf.inter.CXFDemoImpl;

/**
 * CXF拦截器<br>
 * 通过拦截器,进行用户校验.
 * 
 * @author CYX
 *
 */
public class StartMain {

	public static void main(String[] args) {

		String address = "http://localhost:8088/CXFDemo/sayHello";
		EndpointImpl epi = (EndpointImpl) Endpoint.publish(address,new CXFDemoImpl());
		epi.getInInterceptors().add(new AuthInterceptor());
		System.out.println("WebService 发布成功,address : " + address);
	}

}

通过wsdl生成客户端代码就不多说了..去看以前的文章吧...

客户端拦截器

package com.client.interceptor;

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;

/**
 * 客户端拦截器
 * 
 * @author CYX
 * 
 */
public class AddHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

	private String userName;
	private String passWord;

	public AddHeaderInterceptor(String username,String password) {
		super(Phase.PREPARE_SEND);
		this.userName = username;
		this.passWord = password;
	}

	@Override
	public void handleMessage(SoapMessage message) throws Fault {
		List<Header> header = message.getHeaders();

		// 创建Document对象
		Document document = DOMUtils.createDocument();
		Element element = document.createElement("authHeader");

		// 配置服务端Head信息的用户名和密码
		Element userNameElement = document.createElement("userName");
		userNameElement.setTextContent(userName);
		Element passWordElement = document.createElement("passWord");
		passWordElement.setTextContent(passWord);

		element.appendChild(userNameElement);
		element.appendChild(passWordElement);
		header.add(new Header(new QName(""),element));

	}

}


客户端主类

package com.client;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;

import com.client.interceptor.AddHeaderInterceptor;
import com.cxf.inter.CXFDemoImplService;
import com.cxf.inter.CXFInterface;

public class TestClient {

	public static void main(String[] args) {

		CXFDemoImplService cxfDemo = new CXFDemoImplService();
		CXFInterface cxfInter = cxfDemo.getCXFDemoImplPort();
		Client client = ClientProxy.getClient(cxfInter);
		client.getOutInterceptors().add(new AddHeaderInterceptor("cy","123456"));
		String response = cxfInter.sayHello("xycheng");
		System.out.println("response : " + response);
		
	}

}
这里的'cyx' 和 '123456' 要和服务端拦截器中的相匹配..?

正式项目肯定是通过数据库验证..

然后直接运行服务端和客户端就行了...


密码错误

服务端控制台打印


客户端控制台打印信息




密码争取的控制台打印信息

服务端


客户端

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读