企业应用(如 ERP、CRM、OA 和 HR 等)是企业信息系统的核心资产,支撑企业的生产、经营与管理。随着移动互联网的蓬勃发展,这些企业应用迫切需要向移动设备提供便捷、高效的访问,实现丰富的用户体验。例如,销售人员通过手机 App 管理客户信息、拜访记录和订单等;差旅途中的管理人员在平板电脑上浏览财务报表或审批公文等。此外,集团型的企业客户日益注重 IT 服务能力的输出与共享,以促进各业务板块及生态圈的协同发展。例如,构建统一的身份认证平台为所有的第三方应用提供认证与授权服务。
一般来说,企业应用通过开放 API (Application programming interfaces)的方式实现应用集成与能力共享。例如,SAP 应用(如 ERP/CRM/SRM/SCM/PLM 等)发布的是基于 OData (Open Data Protocol) 协议封装的 API,而且满足 REST 设计风格(关于 OData 协议的更多介绍,请参见 SAP 官方博客)。这些 API 为企业应用在云上的微服务化提供了机会。此外,还需要 API 管理平台对 API 进行统一的管理,包括发布与部署、安全认证、流量控制和监控告警等。Amazon API Gateway 是实现 API 管理平台的托管式服务,它提供了统一、安全、敏捷及可扩展的 API 生产与消费方式。API Gateway 可以创建 API 直接与后台的各类企业应用集成;也可以结合 AWS Lambda,实现定制化的业务逻辑与管理功能,构建轻量级、松耦合的无服务器式微服务。利用 API Gateway 和 Lambda 实现微服务的另外一个显著优势是,可以充分发挥无服务器架构中缓存和动态扩容的特性,降低前端应用对后台企业应用的访问压力,并优化用户体验。关于 API Gateway 的更多特性,请参见产品主页。
我的同事 KK Ramamoorthy 在近期的一篇文章中介绍了利用 API Gateway 部署 SAP API 的方法,移动 App 和 Web 应用可以通过 API Gateway 直接访问 SAP 开放的 OData API endpoints,轻松实现 API 的调用。
根据企业对云上环境的安全分区要求及 AWS 最佳实践,SAP 应用一般是部署在 VPC 的私有子网,不允许被公网直接访问,因此,API Gateway 无法创建 API 直接调用位于私有子网的 OData API endpoints。此外, OData API 采用了安全令牌机制防范 CSRF (Cross-site request forgery) 攻击(即在调用 POST 方法之前必须先请求获得 X-CSRF-Token),这一机制也限制了 API Gateway 直接对 SAP 应用进行微服务化。针对上述两个问题,本文将介绍通过 Lambda 函数结合 API Gateway 实现安全、灵活的 SAP 应用微服务。Lambda 函数完成的工作机制如下:
作为 API Gateway 的代理,将调用请求转发到位于私有子网的 OData API endpoint;
对于 API Gateway 的 GET 方法,直接提交 GET 请求;
对于 API Gateway 的 POST 方法,先请求 CSRF 令牌,再提交 POST 请求;
实现基本的身份认证(用户名与密码)。
部署架构
在 VPC 私有子网中部署 SAP 应用。其中,SAP Gateway 是 OData API 的开发和运行环境,SAP 后台应用可以是 ERP/CRM/SCM 等。本示例采用的是 S/4 HANA(内嵌了 Gateway)。启用 Gateway 内置的 “RMTSAMPLEFLIGHT” 服务。该示例服务提供了一组管理航班旅行的 OData API。在后续的示例中,将展示如何在 API Gateway 创建 API 以查询和添加旅行社信息。
在 VPC 公共子网中部署 Lambda 函数 ”sapapi-proxy”,作为 API Gateway 调用后台 OData API 的代理。
定义安全组 “SAP” 对 SAP S/4 HANA 进行隔离保护,即只允许来自安全组 “SAP Proxy” 的 Lambda 函数访问 OData API。
必须为 VPC 中的 Lambda 函数分配网络接口即 ENI (Elastic Network Interfaces) ,因此,需要定义 AWS IAM 权限策略,授予 Lambda 函数管理 ENI 的权限。
在 Amazon CloudWatch Logs 创建 Flow Logs,对 API 调用过程中的网络流量进行监控。
以下将针对 API Gateway 的配置和 Lambda 函数的实现展开详细的介绍。
API Gateway 的配置
在 API Gateway 为 OData API 服务创建对应的资源和方法,这样前端应用的调用这些方法的请求将被传递给 Lambda 函数;而 Lambda 函数执行结束后,结果将返回给前端应用。其中,请求和响应内容均是按照预定义的 Body Mapping Templates 转换成 JSON 格式。
创建一个新的 API,并定义 ”travelagency” 的资源,然后声明 GET 和 POST 两个方法,分别用于实现“查询旅行社“和”添加旅行社“的服务调用;
在该资源的“Integration Request” 页面中配置与 Lambda 函数的集成方式(下图以 GET 方法为例);
为 GET 方法定义 URL 查询字符串
“agencynum”
,该字符串是查询请求的参数,例如:“/travelagency?agencynum=00000055”;
为 GET 方法定义如下的 Body Mapping Template,从而 API Gateway 可以捕捉到请求里的必要参数信息并传递给 Lambda 函数,包括 SAP 应用的私网地址、端口、OData 服务路径、认证信息以及查询字符串
“agencynum”
;
为 POST 方法定义如下的 Body Mapping Template,其中,JSON 格式的 ”body” 是该方法的主要参数,定义了将要提交给 OData API 的数据,例如以下是待添加的旅行社信息:
Json
Lambda 函数的实现与部署
采用 Node.js 实现的 Lambda 函数负责:a). 接收 API Gateway 传递过来的请求和参数,根据不同的方法,转发给后台的 OData API endpoints;b). 针对 POST 方法,先调用 HTTP GET 方法请求 X-CSRF-Token 和 Cookie,然后调用 HTTP POST 方法提交待添加的数据;c). 将 OData API endpoints 的响应结果返回给 API Gateway。
创建执行 Lambda 函数所需的 IAM 角色 “LambdaVpcProxyExecutionRole”,采用的权限策略如下:
Json
创建 Lambda 函数 “sapapi-proxy”, 并赋予刚刚创建的 IAM 角色;
配置 Lambda 函数访问的 VPC 信息,包括子网和安全组(注意:AWS 要求至少选择 2 个子网以在高可用性模式下运行 Lambda 函数);
实现 Lambda 函数,以下是接收请求和返回响应的主函数体代码:
Js
处理 GET 方法的 “getTravelAgency” 函数代码如下图所示:
Js
处理 POST 方法的 “postTravelAgency” 函数代码如下图所示:
Js
测试
使用 Postman 对 API 进行测试,以下是调用 GET 方法即查询旅行社的测试结果。其中,”body” 是 SAP 返回的 JSON 格式的 OData 资源描述信息。
以下是调用 POST 方法即添加新旅行社的测试结果。其中,”body” 是 SAP 返回的 Atom 格式的 OData 资源描述信息。
总结
本文介绍了使用 API Gateway 与 Lambda 实现 SAP 应用的微服务,该方式无需将 OData API endpoints 暴露在公网,从而满足企业应用对于安全合规的要求;同时, Lambda 函数代理 CRSF 安全令牌的申请,为前端应用提供了更加透明的开发接口。
本示例在 API 调用请求中采用了基础的认证方式(即 HTTP 报文头中的 “Authorization” 字段),但是在生产环境中,建议采用 OAuth 2.0 的认证方式(例如在 Lambda 函数中实现这一认证授权的工作流程)。后续的博客文章将会展开介绍这部分工作。
致谢
感谢宁夏西云数据科技有限公司郭润平对本文示例环境 SAP S/4HANA 镜像的支持。
主要参考链接
作者介绍:
刘玉恒
AWS 资深顾问,拥有丰富的云计算架构咨询服务经验,现致力于企业客户应用迁移、容灾与双活解决方案。曾就职于 VMware 从事咨询服务顾问和技术客户经理等职位。
本文转载自 AWS 技术博客。
原文链接:
https://amazonaws-china.com/cn/blogs/china/aws-lambda-sap/
评论