文档章节

jax-ws之webservice security(安全)续

AbrahamLeeJay
 AbrahamLeeJay
发布于 2014/07/17 07:44
字数 1191
阅读 33
收藏 0

前言:

第一天里说了如何用jax-ws去结合ssh框架。

在今天的教程中将会向大家详细讲述一个ws-security中的一个传统的”基于handler”来认证客户端传来的用户名密码的webservice.

客户端传过来一对用户名和密码,服务端进行认证。

当然,我们此处说这个用户名和密码的传送,那可不是用下面的这种形式来传送的哦:  http://xxx.do?username=xxx&password=xxx

我们这个用户名和密码是带在soap报文中的, jax-ws用一个handler专门用于处理soap报文的。

一、书写Handler

1. 1 handler类

package ctsjavacoe.ws.fromjava;

import java.util.*;

import javax.servlet.http.HttpServletRequest;

import javax.xml.namespace.QName;

import javax.xml.soap.*;

import javax.xml.ws.handler.MessageContext;

import javax.xml.ws.handler.soap.*;

import javax.xml.ws.soap.SOAPFaultException;

import org.apache.cxf.transport.http.*;

public class AuthValidationHandler implements SOAPHandler<SOAPMessageContext> {

         public Set<QName> getHeaders() {

                   // TODO Auto-generated method stub

                   return null;

         }

         public void close(MessageContext context) {

         }

         public boolean handleFault(SOAPMessageContext context) {

                   return false;

         }

         public boolean handleMessage(SOAPMessageContext context) {

 

                   HttpServletRequest request = (HttpServletRequest) context

                                     .get(AbstractHTTPDestination.HTTP_REQUEST);

                   //

                   if (request != null) {

                            System.out.println("Client IP:" + request.getRemoteAddr());

                   } else {

                            System.out.println("get client ip is null>>>>>>>>>");

                   }

 

                   Boolean outbound = (Boolean) context

                                     .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

 

                   if (!outbound.booleanValue()) {

                            SOAPMessage soapMessage = context.getMessage();

 

                            try {

                                     SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart()

                                                        .getEnvelope();

                                     SOAPHeader soapHeader = soapEnvelope.getHeader();

 

                                     if (soapHeader == null)

                                               generateSoapFault(soapMessage, "No Message Header...");

 

                                     Iterator it = soapHeader

                                                        .extractHeaderElements(SOAPConstants.URI_SOAP_1_2_ROLE_NEXT);

 

                                     if (it == null || !it.hasNext())

                                               generateSoapFault(soapMessage,

                                                                 "No Header block for role next");

 

                                     Node node = (Node) it.next();

 

                                     String value = node == null ? null : node.getValue();

 

                                     if (value == null)

                                               generateSoapFault(soapMessage,

                                                                 "No authation info in header blocks");

 

                                     String[] infos = value.split("&");

 

                                     return authValidate(infos[0], infos[1]);

 

                            } catch (SOAPException e) {

                                     e.printStackTrace();

                            }

 

                   }

                   return false;

         }

         private boolean authValidate(String userName, String password) {

                   if (userName == null || password == null) {

                            return false;

                   }

 

                   if ("admin".equals(userName) && "admin".equals(password)) {

                            return true;

                   }

                   return false;

         }

 

         private void generateSoapFault(SOAPMessage soapMessage, String reasion) {

                   try {

                            SOAPBody soapBody = soapMessage.getSOAPBody();

                            SOAPFault soapFault = soapBody.getFault();

 

                            if (soapFault == null) {

                                     soapFault = soapBody.addFault();

                            }

 

                            soapFault.setFaultString(reasion);

 

                            throw new SOAPFaultException(soapFault);

 

                   } catch (SOAPException e) {

                            // TODO Auto-generated catch block

                            e.printStackTrace();

                   }

         }

 

}

上面这段代码看似很长,其实逻辑很简单,注意:

publicboolean handleMessage(SOAPMessageContext context)这个方法。

Handler会先检查,这个soap是in还是out,当然,对于我们来说要验证客户端提交上来的用户名和密码,因该是in。

因此,如果这个soap是in,并且含有soapheader(我们的用户名密码是含在soap header中的,可不是通过url以http://xxx.xxx.xxx/xxx.do?username=xxx&password=xxx这样的形式传输的哦,这样做是彻头彻尾的作弊,不对的作法,和掩耳盗铃没啥区别),并且含有soap header,这个soap header中会提取出“username&password”这样的一个字符串,然后进行用户名和密码的比对与校验。


1.2handler类的XML描述

我们有了Handler类,还需要有一个handler的xml文件,对该类进行描述,这个xml文件和handler类放在同一层java的package下,该XML名为:handlers.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">

    <handler-chain>

        <handler>

            <handler-name>authHandler</handler-name>

             <handler-class>

ctsjavacoe.ws.fromjava.AuthValidationHandler

</handler-class>

        </handler>

    </handler-chain>

</handler-chains> 

二、书写Webservice并引用handler

2.1 接口

package ctsjavacoe.ws.fromjava;

import javax.jws.WebMethod;

import javax.jws.WebService;

import javax.jws.soap.SOAPBinding;

import javax.jws.soap.SOAPBinding.Style;

@WebService

@SOAPBinding(style = Style.RPC)

public interface AuthorServer {

         @WebMethod

         public String sayHello(String name);

}

2.2 实现类

package ctsjavacoe.ws.fromjava;

 

import javax.jws.HandlerChain;

import javax.jws.WebService;

@WebService(endpointInterface = "ctsjavacoe.ws.fromjava.AuthorServer")

@HandlerChain(file = "handlers.xml")

public class AuthorServerImpl implements AuthorServer {

         public String sayHello(String name) {

                   return "Hello: " + name;

         }

}

核心是这一行:@HandlerChain(file= "handlers.xml")。

把它编译成webservice,然后发布工程到tomcat中去吧。

得到wsdl: http://localhost:8080/JaxWSSample/AuthorServerService?wsdl

我们用SOAPUI来调用这个webservice试试效果:

大家可以看到入到的output是:<faultstring>No Header blockfor role next</faultstring>

三、书写客户端

根据wsdl先得到相关的stub。

3.1 书写client端的handler类

package ctsjavacoe.ws.fromjava;

import java.util.Set;

import javax.xml.namespace.QName;

import javax.xml.soap.*;

import javax.xml.ws.handler.MessageContext;

import javax.xml.ws.handler.soap.SOAPHandler;

import javax.xml.ws.handler.soap.SOAPMessageContext;

public class ClientAuthenticationHandler implements SOAPHandler<SOAPMessageContext> {

         public Set<QName> getHeaders() {

                   // TODO Auto-generated method stub

                   return null;

         }

         public void close(MessageContext arg0) {

                   // TODO Auto-generated method stub

         }

         public boolean handleFault(SOAPMessageContext arg0) {

                   // TODO Auto-generated method stub

                   return false;

         }

         public boolean handleMessage(SOAPMessageContext ctx) {

                   Boolean request_p = (Boolean) ctx

                                     .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

 

                   if (request_p) {

                            try {

                                     SOAPMessage msg = ctx.getMessage();

                                     SOAPEnvelope env = msg.getSOAPPart().getEnvelope();

                                     SOAPHeader hdr = env.getHeader();

 

                                     if (hdr == null)

                                               hdr = env.addHeader();

 

                                     QName qname_user = new QName("http://fromjava.ws.ctsjavacoe/",

                                                        "AuthorServerImplService");

                                     SOAPHeaderElement helem_user = hdr.addHeaderElement(qname_user);

                                     helem_user.setActor(SOAPConstants.URI_SOAP_1_2_ROLE_NEXT);

                                     helem_user.addTextNode("admin&admin1");

                                     msg.saveChanges();

                                     //msg.writeTo(System.out);

                                     return true;

                            } catch (Exception e) {

                                     e.printStackTrace();

                            }

                   }

                   return false;

         }

}

该handler类主要的核心方法为:

public booleanhandleMessage(SOAPMessageContext ctx)方法

该方法中需要注意的是:

QName qname_user = new QName("http://fromjava.ws.ctsjavacoe/",

                                                        "AuthorServerImplService");

SOAPHeaderElement helem_user = hdr.addHeaderElement(qname_user);

helem_user.setActor(SOAPConstants.URI_SOAP_1_2_ROLE_NEXT);

helem_user.addTextNode("admin&admin1");

msg.saveChanges();

我们通过上述的语句就已经知道我们会在客户端传过去一对用户名与密码,它们是:

username=admin

password=admin1

3.2 书写客户端

package ctsjavacoe.ws.fromjava;

 

import java.util.*;

 

import javax.xml.ws.handler.Handler;

import javax.xml.ws.handler.HandlerResolver;

import javax.xml.ws.handler.PortInfo;

public class AuthorServerClient {

         public static void main(String[] args) {

                   AuthorServerImplService service = new AuthorServerImplService();

                   service.setHandlerResolver(new HandlerResolver() {

                            public List<Handler> getHandlerChain(PortInfo arg0) {

                                     List<Handler> handlerList = new ArrayList<Handler>();

                                     handlerList.add(new ClientAuthenticationHandler());

                                     return handlerList;

                            }

                   });

                   AuthorServer authorService = service.getAuthorServerImplPort();

                   String msg = authorService.sayHello("MK");

                   System.out.println("rtn msg=====" + msg);

         }

}

 

 


四、运行上述例子后出错啦?为什么?

运行后我们得到了如下的输出:


出错了?为什么?

我们回过头来看两个handler,一个是server端的handler,其中:

if ("admin".equals(userName) && "admin".equals(password)) {

                            return true;

         }

一个是client的handler类,其中:

helem_user.addTextNode("admin&admin1");

啊。。。因为server端的密码要求是”admin”不是”admin1”,于是我们把client端的密码也改成”admin”,再次运行我们的客户端,得到输出:

完成第二天的教程


© 著作权归作者所有

AbrahamLeeJay
粉丝 21
博文 56
码字总数 105294
作品 0
武汉
高级程序员
私信 提问
jax-ws之webservice security(安全)续

前言: 在前面的“5天学会jaxws-webservice教程”,我们讲了基本的jax-ws的使用。 Jax-ws是业界公认的标准的webservice,它已经成为了一个行业界标准,包括cxf,其实cxf也是调用的jax-ws为标...

AbrahamLeeJay
2014/07/17
51
0
基于SOA 思想下的WebService实战资料分享

跟大家分享基于SOA 思想下的WebService实战(电子商务需求,分析,架构全涉及,百万数据优化) 课程讲解内容涵盖: 第1章 CXF框架快速起步(2课时) Webservice技术规则 Java-WebService技术规范...

abcfhl
2013/06/24
2.1K
7
jax-ws之webservice security(安全)

前言: 在今天的学习中,我们讲开始过渡到一个真正的websecurity例子。 第二天中我们知道了如何使用handler来处理客户端提交上来的用户名与密码,而在今天的学习中,我们将会使用服务端预先配...

AbrahamLeeJay
2014/07/17
137
0
jaxws-webservice编程(第一个记录)

随着近几年来,SOA,EAI等架构体系的日渐成熟,Webservice越来越炽手可热,尤其是在企业做异质平台整合时成为了首选的技术。 Java的Webservice技术更是层出不穷,比较流行的有:Axis2,Sprin...

heroShane
2014/02/28
2.3K
0
jaxws-webservice编程

前言: 随着近几年来,SOA,EAI等架构体系的日渐成熟,Webservice越来越炽手可热,尤其是在企业做异质平台整合时成为了首选的技术。 Java的Webservice技术更是层出不穷,比较流行的有: Axis...

AbrahamLeeJay
2014/07/17
372
0

没有更多内容

加载失败,请刷新页面

加载更多

Tensorflow 2.0安装

Tensorflow2.0安装环境: Ubuntu 16.04或更高(64位) Windows 7或者更高(64位,且支持python3) 安装Tensorflow 2.0 GPU版本的需要安装NVIDIA相关软件包: NVIDIA驱动 :版本必须410.x或更...

JosiahMg
20分钟前
4
0
TL138/1808/6748F-EasyEVM开发板硬件、CPU、FLASH、RAM

TL138/1808/6748F-EasyEVM是广州创龙基于SOM-TL138/SOM-TL1808/SOM-TL6748F核心板开发的一款开发板。由于SOM-TL138/SOM-TL1808/SOM-TL6748核心板管脚兼容,所以此三个核心板共用同一个底板。...

Tronlong创龙
28分钟前
4
0
百度嵌入式AI解决方案EdgeBoard之内存驱动设计介绍

1. 背景介绍 由于 FPGA 具备可编程和高性能计算的特点,基于FPGA硬件的AI计算加速,正广泛地应用到计算机视觉处理领域。其中极具代表性的部署方式之一就是使用FPGA和CPU组合构成异构计算系统...

AI君
34分钟前
6
0
开放应用模型(OAM):全球首个云原生应用标准定义与架构模型

Kubernetes 项目作为容器编排领域的事实标准, 成功推动了诸如阿里云 Kubernetes (ACK)等云原生服务的迅速增长。但同时我们也关注到,Kubernetes 的核心 API 资源比如 Service、Deploymen...

Mr_zebra
37分钟前
4
0
《Linux操作系统-Exynos4412》编译和安装Busybox

开发环境:Exynos4412-iTOP-4412开发板 现在 Busybox 的配置已经完成了,接下来开始编译 Busybox,在 Ubuntu 的终端输入 “make”命令开始编译 Busybox,如下图。 下图为编译过程中的截图。 ...

书白
40分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部