使用jMeter对基于SAP ID service进行Authentication的Restful API进行并发测试
这篇文章本来Jerry只在SAP社区上写了英文版的,可以通过点击文末的“阅读原文”获得。后来有两位做Marketing Cloud开发的德国同事,写邮件询问关于文章的更多细节,声称这种方式对他们自己的API性能测试很有用,所以我觉得还是值得用中文再写一遍。

在SAP官网api.sap.com里有大量发布的API,方便合作伙伴和客户自开发应用同SAP解决方案进行集成。

比如Jerry上个月做的一个项目,就是和国内一家专注于提供人脸识别技术解决方案的企业合作, 用户通过微信扫码从而完成人脸识别后,在用户授权的情况下,会调用SAP Marketing Cloud的contact API,生成对应的contact数据,并且将人脸识别得出的面部特征码通过Marketing Cloud扩展字段的方式一并存入contact数据中。
因为这个项目最后会在2019年6月5日于上海举行的SAP云大会上展示,所以当时Jerry完成集成工作后心想,还是得提前测试一下咱们的Marketing Cloud在响应并发请求时的性能, 做到心里有数。

我们在SAP上海云大会上演示的场景是,将SAP Marketing Cloud的Launchpad通过大屏幕投影出来,参会嘉宾完成人脸识别后,Marketing Cloud contact创建API自动被调用,在系统生成contact数据,并且Launchpad contact tile的计数器加一。


所以下一步就是如何模拟大量对Marketing Cloud API的并发请求。
对于程序员来说,最容易想到的方式就是自己动手写一个程序来发送大量请求。Jerry选择的最简单的编程方式,在Java程序里新建大量线程,每个线程发送一个请求,当然也可以直接用JDK里提供的线程池库。我的Java程序源代码在github上:
https://github.com/i042416/JavaTwoPlusTwoEquals5/tree/master/src/odata
除了自己动手编写代码外,还可以重用一些API测试工具来达到同样的目的。Postman是一个API开发人员常用的接口调试利器,它也有定义变量和简易的编程功能:

可以通过称之为Collection Runner的功能,一键运行Collection里的多个请求。

Jerry在这篇SAP社区博客里详细介绍过Postman的编程:
Just a single click to test SAP OData Service which needs CSRF token validation
https://blogs.sap.com/2019/06/10/sap-just-a-single-click-to-test-sap-odata-service-which-needs-csrf-token-valid/
Jerry还在成都C4C开发团队时,组内同事就告诉过我,jMeter是另一个功能强大的基于Java的API压力测试工具。所以这次我选择用jMeter来对API做压力测试。
下文介绍的内容需要大家对jMeter的使用有最基本的了解,如果还不太熟悉的朋友,可以先查阅jMeter的官方文档。
总的思路就是使用jMeter提供的Thread Group(线程组)和控制器这两个工具。Thread Group帮助工具使用者实现了通过多线程发送HTTP请求的功能,比如下图设定的100,意思是通过100个线程同时发送请求。

而涉及到对系统进行写操作的SAP API,比如新建,修改或者删除数据的SAP OData服务,在请求的HTTP头部必须附带防止跨域请求伪造攻击的CSRF token(有时又称XSRF token:Cross-site request forgery). 我们可以将从服务器获取CSRF token的请求和真正调用contact API的请求放到同一控制器里,这样能确保同一线程内,拿token和创建contact这两个请求依次执行。

SAP云平台的官网上有一个帮助文档,对用户访问SAP云平台上的服务的Authentication流程做了清晰的阐述:
https://cloudplatform.sap.com/scenarios/usecases/authentication.html

这张图描述了在Authentication场景下,几个名词User(有时称为Client), Service Provider和Identity Provider(途中简写成IdP)的相互作用关系。
虽然Jerry本文介绍的场景,我用jMeter消费的是Marketing Cloud上的服务,而非SAP云平台上的服务,不过这些服务对应的Idp都是SAP ID service,即accounts.sap.com, 因此Authentication原理仍然相同。
我们牢牢记住这张图的几个步骤,因为我们接下来用jMeter消费Marketing Cloud API时,同样要遵循这种Authentication流。
我们先用Chrome访问SAP Marketing Cloud Fiori Launchpad,来深入理解图中介绍的Authentication流程。
- 浏览器打开SAP Marketing Cloud Fiori Launchpad链接,HTTP请求发送到了Marketing Cloud系统,后者可以视为Service Provider。 
- Marketing Cloud把请求通过HTTP 302重定向了它预先配置好的IdP上去,即SAP ID service(也就是account.sap.com). 

关于什么是SAP ID service,可以查看SAP官方帮助文档:
- IdP的职责是完成实际的用户认证工作,它给用户返回一个登录页面,要求其输入用户名和密码。

上图显示的是SAP ID Service的登录页面,UI虽然简单,但是这个页面的源代码里存在很多隐藏字段。
用Chrome开发者工具能够发现这些隐藏字段:

xsrfProtection
spId
spName
authenticity_token
idpSSOEndpoint
这些字段都是在SAP ID Service的服务器端生成,然后返回给客户端。
- 用户输入密码点击登录按钮后,用户输入的用户名和密码,同第三步介绍的登录页面的隐藏字段,会一齐返回给SAP ID Service服务端。可以在Chrome开发者工具里观察到这些字段位于HTTP请求头部。

- IdP完成用户认证,颁发一个"assertion"响应,值存储于HTTP响应头部的SAMLResponse字段里。

这个字段的SAML表明这是一个基于SAML协议的认证过程,把上图Chrome开发者工具里观察到的SAMLResponse字段值通过BASE64解码,得到下图的XML格式的assertion内容:

上图第一处用红色矩形框高亮的字段是assertion的状态,值为success. 因为SAP ID Service和Marketing Cloud系统配置为互相信任,所以这意味着SAP ID Service通知Marketing Cloud,这个用户的认证已经通过了。
SAML协议规范的官方文档:
http://saml.xml.org/saml-specifications
有了上述的理论基础后,进行jMeter项目的配置工作思路也就清楚了。
我把jMeter项目的工程文件放到我的Github上了,方便大家重用:
在jMeter里,我们按照SAP官网认证架构图的6个步骤来配置:

- 使用jMeter提供的正则表达式提取器,将认证流程第3个步骤,IdP返回的登录页面的5个隐藏字段的值提取出来,存储成jMeter变量:

下图显示了这些隐藏字段的值被成功提取出来并存储成jMeter变量:

- 把第一步提取出并存储在jMeter变量中的五个字段的值(下图红色)的值,再加上用户手动输入的用户名和密码(下图蓝色), 作为请求的头部字段,一齐提交给SAP ID service:

登录成功后,收到了服务器端返回的Cookie值:

- 发送新的请求给服务器,获取CSRF token. 这个请求的响应里包含了两个下图高亮的Cookie,需要同样存储成jMeter变量,以供最后一个请求使用。

- 最后一个步骤,将前一步获取到的CSRF token附加到HTTP请求字段中,同时带上前一步服务器返回的两个Cookie字段:

至此这个jMeter项目的配置工作就完成了,其优于Java编程和Postman之处在于我们不需要编写一行代码,我们对API进行并发测试这个需求的相关功能点全部能够通过jMeter里的配置完成。

最后简单测试一下并发请求的响应时间:

我在使用jMeter调用contact API创建工作时用到了简单的随机数生成器,在contact的姓后面加上了简单的随机数,这是最后通过jMeter生成的contact在Marketing Cloud里的显示:

最后一步就是把SAP Marketing Cloud Launchpad里的contact tile的计数器刷新间隔设置成10秒刷新一次:

系统显示,在2019年6月5日上海SAP云大会这个演示场景的展台上,一共有276个嘉宾完成了人脸识别后的Marketing Cloud contact注册流程。

要获取更多Jerry的原创文章,请关注公众号"汪子熙":

使用jMeter对基于SAP ID service进行Authentication的Restful API进行并发测试的更多相关文章
- 基于Node的PetShop,oauth2认证RESTful API
		前篇 - 基本认证,用户名密码 后篇 - OAuth2 认证 前文使用包passport实现了一个简单的用户名.密码认证.本文改用oauth2来实现更加安全的认证.全部代码在这里. OAUTH2 用户 ... 
- 基于SAML2.0的SAP云产品Identity Authentication过程介绍
		SAP官网的架构图 https://cloudplatform.sap.com/scenarios/usecases/authentication.html 上图介绍了用户访问SAP云平台时经历的Au ... 
- SAP Tax Service可以取代TAXBRA / RVABRA吗?(翻译) 跨国贸易云税务解决方案
		这篇文章的内容基于Fausto Motter 的一篇文章,他在SAP社区用葡萄牙语写了一篇文章,讨论如何用云解决方案取代巴西税收计算.我翻译了他的部分文章,添加并修改了一些内容,目标是帮助全球的SA ... 
- 基于SAP Kyma的订单编排增强介绍
		尽管有一万个舍不得,2018年还是无可挽回地离我们远去了. 唯有SAP成都研究院的同事和我去年在网络上留下的这些痕迹,能证明2018年我们曾经很认真地去度过每一天: SAP成都研究院2018年总共87 ... 
- SAP Web Service简介与配置方法
		[版权声明]本文为博主原创文章,转载请在明显位置注明出处. 一. SAP Web Service简介 二. SAP Web Service配置准备工作 1. 通过RZ10配置服务器名称和其他参数 2. ... 
- 原创:XXX公司-基于SAP的库存管理系统解决方案
		XXX公司-基于SAP的库存管理系统 解决方案 版本:V0.3.0 Excel_Cortan 文件状态: [ ] 草稿 [ ] 正式发布 [√] 正在修改 文件标识: 当前版本: V0.3 作 者 ... 
- Jmeter接口测试-基于nodejs的to do list项目说明
		一.了解测试项目 我们的测试项目叫做smile_task,简称sm_task.这是一个基于nodejs超简单的todo list. 它的主要流程就是:输入标题描述---点击创建一个任务---编辑修改任 ... 
- 使用 node-odata 轻松创建基于 OData 协议的 RESTful API
		前言 OData, 相信身为.NET程序员应该不为陌生, 对于他的实现, 之前也有童鞋进行过介绍(见:这里1,这里2). 微软的WCF Data Service即采用的该协议来进行通信, ASP.NE ... 
- 基于RYU restful api实现的VLAN网络虚拟化
		基于RYU restful api实现的VLAN网络虚拟化 前言 本次实验是基于OVS的VLAN虚拟化简易实践方案的进一步的实验,采用RYU restful api进行配置.本质上和上次实验没什么差, ... 
随机推荐
- EasyUI实现图片的上传后与其他文本框的提交以及DataGrid中图片的展示
			图片即文件,在jsp中文件上传很简单,一个type为file的input,一个form指定enctype为multipart/form-data,通过post提交到后台利用apache的commons ... 
- java设置北京时间的时区
			java设置北京时间的时区 解决方法: 设置北京时间的时区,消除时间差. TimeZone timeZone = TimeZone.getTimeZone("GMT+8"); ... 
- java 利用poi 实现excel合并单元格后出现边框有的消失的解决方法
			使用工具类RegionUtil CellRangeAddress cra = new CellRangeAddress(nowRowCount, nowRowCount + followSize-1, ... 
- 【418】C语言ADT实现Quack(stack+queue)
			quack.h #include <stdio.h> #include <stdlib.h> #include <assert.h> typedef struct ... 
- VCL组件之TPanel
			TPanel位于Standard组件面板上,也是常用的一种容器控件.面板的一个优点就是放在面板上的组件称为面板的一部分,因此它们与面板一起移动.这在设计阶段很有用. Panel组件的大部分功能在于其A ... 
- Halcon 学习2 金属雕刻字识别
			*HALCON 里面的例程名称:engraved_cnn.hdevread_image (Image, 'engraved')get_image_size (Image, Width, Height) ... 
- java基本思想
			面向对象 众所周知,面向对象编程思想是java的基本思想.java的整个体系和技术实现都是以这个思想为基础.(这个通过类和接口能看出来,后面提到) 对这个事情的认知度甚至变成了很多公司的面试标准.比如 ... 
- 学习docker笔记1
			docker是一个能够把开发应用程序自动部署到容器的开源引擎 docker通过namespace实现了资源隔离,通过cgroups实现了资源限制,通过写时复制机制(copy-on-write)实现了高 ... 
- python面向对象学习笔记(一)
			粘贴一些自学过程中的笔记大纲,源文本在pycharm里面写的,有点乱整理一下,部分内容有待补充,书写不一定100%正确,全当数据备份了. 1.面向对象的特性 #你写代码时什么使用面向对象 #处理比较复 ... 
- db2 数据库配置HADR+TSA添加集群节点
			Db2配置HADR高可用+TSA添加集群节点 一.服务器资源 Master IP:10.78.10.1 数据库:dbclassSlave IP:10.78.10.2 数据库:dbclassVIP:10 ... 
