使用OAuth进行SAP和其他系统进行网络通信的例子

之前在SAP系统(ABAP)上实现了和ServiceNow的OAuth通信(ServiceNow是一个IT服务系统),本文将会介绍具体实现步骤,考虑到ServiceNow在国内用的公司少,我会把重点放在SAP部分。另外建议去了解一下OAuth标准协议,这样可以更好地理解OAuth的整体流程,也对以后在其他系统上实现OAuth有帮助。

 

我先用简单的文字描述一下OAuth的使用场景,A(客户端)访问B(服务器),一种比较普遍的方式是A用B的用户名和密码访问,这样有一个问题是,当A不是可信任系统时,把用户名及密码告诉A会有安全风险。而使用OAuth的话,A首先需要获得B的授权,获得一个token(令牌),之后根据这个token访问B,这样A就不需要B的用户名和密码了。这里举一个微信授权的使用场景,平时我们在访问一些小程序的时候,会弹出一个框让我们确定是否允许小程序使用微信的头像及昵称等信息,这个就是授权,当你同意的时候,微信会授予小程序一个token,之后小程序根据token就可以访问微信里的头像等资料,而不需要微信的用户名及密码。需要注意的是,OAuth侧重的是授权(Authorization),而非认证(Authentication)。

 

先讲SAP系统作为客户端,ServiceNow作为服务器的场合。在讲具体实现步骤之前,首先分析下在当前使用场景中,OAuth的各个角色分别是什么,虽然这不是具体实现的一部分,但是有助于理解OAuth

Resource Owner: ServiceNow user

Resource Server: ServiceNow

Client: Postbox

Authorization Server: ServiceNow

Authorization Grant: Authorization Code

 

相关的权限

ServiceNow: admin

SAP: https://help.sap.com/viewer/3c4e8fc004cb4401a4fdd737f02ac2b9/7.5.9/en-US/6f679081b5444f91bf68e600025c2cf6.html

 

相关的服务或者配置

ServiceNow: 默认打开

SAP:

https://www.abc.com:443/sap/bc/webdynpro/sap/oa2c_config

https://www.abc.com:443/sap/bc/sec/oauth2/client/grant/authorization

https://www.abc.com:443/sap/public/bc/sec/oauth2/client/redirect

注:https://www.abc.com:443只是举个例子,在实际项目里需要替换成自己的URL。

 

实现步骤

首先需要在ServiceNow注册一个Client(相当于备案)。

使用OAuth进行SAP和其他系统进行网络通信的例子

 

Client ID和Client Secret相当于Client的用户名和密码,在之后SAP设置那边会用到。Redirect URL是token的申请者的回调服务地址,这个地址可以在之后SAP配置中获得,也可以通过查阅SAP官方文档得知。Access Token和Refresh Token的Lifespan是两个token的有效期,这个之后在token有效期部分会具体解释作用及设置。

 

现在到SAP这边,先去t-code OA2C_TYPES,定义一个OAuth Provider类型SNOW。

使用OAuth进行SAP和其他系统进行网络通信的例子

 

然后在SE80里,选择上面的类型,创建一个OAuth Client的Profile,scope是资源服务器里预先定义好的,ServiceNow的话,这里填useraccount就可以了。

使用OAuth进行SAP和其他系统进行网络通信的例子

 

之后去t-code OA2C_CONFIG,选择刚刚创建的Client Profile进行配置。

使用OAuth进行SAP和其他系统进行网络通信的例子

Client ID和Secret就是之前在ServiceNow里定义的,认证和获取token的服务地址需要填一下,这两个地址可以从ServiceNow的官方文档中获取。Redirection服务相关的URL是自动生成的,刚刚在ServiceNow里注册Client的时候需要的Redirection URL就是指这里的。SAML选项可以勾掉,本文介绍是授权码的方法获取token,不需要用到SAML。Validity跟token的有效期有关,会在之后的有效期部分详细解释。

 

现在ServiceNow和SAP两边的配置都完成了,可以进行OAuth授权了,有两种方法。

1,使用t-code OA2C_GRANT

使用OAuth进行SAP和其他系统进行网络通信的例子

 

2,https://www.abc.com:443/sap/bc/sec/oauth2/client/grant/authorization?profile=/SVX/SNOW

 

这两种方法都会进入到ServiceNow授权的网址,如果这时你还没有登录,则需要先登录。

使用OAuth进行SAP和其他系统进行网络通信的例子

点击Allow,意味着你所登录的ServiceNow的用户(作为Resource Owner),授权给SAP用户(作为Client),授权完成后然后会根据之前设置的Redirect URL跳转回SAP。

 

如果获取token成功了,下图里的status会显示绿色。

使用OAuth进行SAP和其他系统进行网络通信的例子

 

之后可以运行代码发起请求了,下面的代码是个例子,只需要填写http client和OAuth profile就可以了。

TRY.
    CALL METHOD cl_oauth2_client=>create
      EXPORTING
        i_profile        = '/SVX/SNOW'
      RECEIVING
        ro_oauth2_client = lo_oa2c_client.

  CATCH cx_oa2c INTO lx_oa2c.
    lv_text = lx_oa2c->get_text( ).
    WRITE lv_text.
    RETURN.
ENDTRY.

TRY.
    CALL METHOD lo_oa2c_client->set_token
      EXPORTING
        io_http_client = lo_http_client.
  CATCH cx_oa2c INTO lx_oa2c.
    lv_text = lx_oa2c->get_text( ).
    WRITE lv_text.
    TRY.
        CALL METHOD lo_oa2c_client->execute_refresh_flow.
      CATCH cx_oa2c INTO lx_oa2c.
        lv_text = lx_oa2c->get_text( ).
        WRITE lv_text.
        RETURN.
    ENDTRY.
    TRY.
        CALL METHOD lo_oa2c_client->set_token
          EXPORTING
            io_http_client = lo_http_client.
      CATCH cx_oa2c INTO lx_oa2c.
        lv_text = lx_oa2c->get_text( ).
        WRITE lv_text.
        RETURN.
    ENDTRY.
ENDTRY.

 

在运行代码之前,有个默认配置还需要改一下(t-code OA2C_CONFIG)。

使用OAuth进行SAP和其他系统进行网络通信的例子

这里原本设置的是Form Field,需要改成Header Field,因为ServiceNow的token解析可能需要token放在header里。

 

Token有效期

之前在ServiceNow和SAP配置时,两边都有token有效期的设置。

使用OAuth进行SAP和其他系统进行网络通信的例子

使用OAuth进行SAP和其他系统进行网络通信的例子

 

ServiceNow里单位数字单位是秒,SAP则是天(-1代表无有效期,也就是长期有效)。在发起HTTP请求时,系统会先检查access token有没有过期,如果过期的话,会根据refresh token再去获取一个新的access token,如果refresh token也过期了(有两个refresh token的过期时间,两个时间都会检查),那就是需要上面的授权步骤重新再来一遍了。另外需要注意,这两边有效时间的设置,都是只有在授权那下时才生效的,如果授权完之后再改是没用的。

 

 

代理服务器

有时候两个服务器通信是需要代理服务器的,这时一个解决方法是在SICF里代理设置里面配置代理服务器。如果没有配置的话,在请求授权获取token的时候会有网络连接错误,因为标准代码里获取token也是使用HTTP请求的,这部分代码里是没有设置代理的。

 

用户类型

在OAuth使用场景里,Resource Owner和Client都是一个具体的用户,但SAP这边用户类型比较多,我在使用OAuth授权时,碰到的情况是SAP用户是一个系统用户(System User)而不是一个会话用户(Dialog User),并且密码是保密的,只有系统管理员才知道。后来的解决方法是先改成会话用户并临时设置一个密码,完成授权后再改回去。

 

Enhancement Spot/BADI

在SAP官方文档或者Wiki里,可以看到有增强的部分,当标准的OAuth配置无法满足需求的时候,比如服务器要求一些额外的参数,这时可以使用增强。在本文的使用场景,也就是SAP和ServiceNow通信,使用标准配置就够了,所以没有使用到增强。

 

参考网站

https://help.sap.com/viewer/3c4e8fc004cb4401a4fdd737f02ac2b9/7.5.9/en-US/81c09e3f183e49e4b1eb6959ccbe6e84.html

https://docs.servicenow.com/bundle/london-platform-administration/page/administer/security/task/t_SettingUpOAuth.html