这是Jerry 2020年的第48篇文章,也是汪子熙公众号总共第231篇原创文章。
最近Jerry把这个公众号之前发布的总共230篇文章按照类别整理了一系列合集出来,比如所有的ABAP文章,放在了这个合集里:汪子熙的ABAP合集。可以通过点击文末的“阅读原文”获得。
本文继续介绍ABAP里的一个知识点:ABAP Netweaver服务器的登录方式(Standard Logon Procedure).
本文的英文版最先发布于SAP社区博客,我当时负责处理客户报过来的关于SAP CRM Web Service的incident,遇到一个HTTP 401错误消息的知识点,发现我理解得不够清楚,因此把SAP帮助文档找来研究了一番,写下了这篇博客:
Learn more detail about Standard logon procedure
https://blogs.sap.com/2014/05/21/learn-more-detail-about-standard-logon-procedure/
我们在事务码SICF里随便打开一个节点,在标签页Logon Data里发现Procedure这个字段,设置的默认值为Standard,按F1可以查看帮助文档。
如果对于SICF节点在ABAP Netweaver服务器里扮演的角色感兴趣,可以参考Jerry的文章:一个13年ABAP老兵的建议:了解这些基础知识,对ABAP开发有百利而无一害。
Logon Procedure帮助文档链接:
https://help.sap.com/saphelp_me60/helpdata/en/a9/c8b14025a5c54ee10000000a1550b0/content.htm?no_cache=true
文档提到,当Procedure设置为Standard时,登录验证将会通过下面的顺序进行:
下面我们就通过一些具体的例子,来理解这些不同的登录方式是如何进行的。
例如直接在浏览器里打开某Web Service的WSDL url:
http://<XXXX>:50078/sap/bc/srt/wsdl/flv_10002A111AD1/bndg_url/sap/bc/srt/rfc/sap/zws_add/506/zjerry1/jerry1?sap-client=506
输入url敲回车,我能看到期望中的WSDL内容。然而我还观察到了一些有趣的现象:地址栏里的http自动被转换成了https,同时工具HTTP Watch里观察到了一个HTTP 307重定向。
这个从HTTP协议端口50078自动重定向到HTTPS端口44378的行为,定义在事务码SMICM的参数里:
也可以通过事务码RZ11,查看参数icm/HTTP/redirect_0的值。
然而,此时我根本没有指定任何用户名和密码,为什么我可以成功看到部署在ABAP Netweaver服务器上,需要通过登录认证后才能访问的资源?
这就是标准登录方式之一的Logon using SAP Logon Ticket (SSO-单点登录)在起作用。
摘录一段SAP帮助文档里对Logon using SAP Logon Ticket (SSO)的说明:
Logon using SAP Logon Ticket (MYSAPSSO2 cookie field). If no logon data is transferred as form fields or header fields, the system then tries to log on using a logon ticket. To enable this, the cookie field MYSAPSSO2 must be set.
用HTTP Watch(Chrome开发者工具也行)观察我访问WSDL发起的HTTP请求,果然发现了一个名为MYSAPSSO2的cookie,这是我之前成功登录服务器之后,服务器颁发给客户端的logon ticket. 登录成功之后,接下来每次再访问同一服务器时,浏览器都会自动将该cookie设置到HTTP请求里,达到无需用户显式提供登录信息,也能成功访问服务器资源的目的。
当我将这个MYSAPSSO2 cookie清除之后,再次访问同一资源,又看到了久违的让我输入用户名和密码的弹出对话框。
这次输入用户名和密码之后,再次看到了WSDL内容,然而此次成功登录,采用的方式不是之前的MYSAPSSO2 Logon Ticket,而是基于用户名和密码的Basic Authentication方式(下图蓝色高亮区域)。
注意到下图绿色高亮区域的set-cookie:用户成功登录后,服务器颁发的MYSAPSSO2 cookie,通过HTTP响应的set-cookie字段, 返回给浏览器。下一次浏览器再访问该资源时,会自动在HTTP请求里带上该cookie字段,又重新使用MYSAPSSO2 Logon Ticket的方式进行登录认证了。
下面是几种通过ABAP代码来访问Netweaver服务器资源时,如何指定登录认证信息的例子。
例1:ABAP代码里未提供任何登录认证信息
SAPGUI里执行上图的ABAP代码,会遇到一个弹出对话框,只有手动输入用户名和密码,该代码才能顺利取回资源。
如果添加一行代码:
lo_http_client->propertytype_logon_popup = if_http_client=>co_disabled.
可以阻止用户名和密码输入的对话框弹出,但此时服务器会直接返回HTTP 401 Unauthorized Error:
例2:在ABAP程序里提供用户名和密码的几种方式
可以通过如下方式提供明文的用户名和密码:
也可以在事务码SM59里创建一个类型为H:HTTP Connection to ABAP System的Destination:
将用户名和密码维护到这个Destination的Logon & Security页面的对应字段去:
然后基于这个Destination创建cl_http_client的实例。这种方式安全性比在代码里直接明文指定用户名和密码要好一些。
当然我也试过,将MYSAPSSO2的cookie值拷贝出来:
直接通过set_cookie方法设置给cl_http_client的实例,一样可以成功访问系统里的资源。
只是cookie有时效性,会过期,因此在生产场景的代码中,需要现用现取。关于ABAP CL_HTTP_CLIENT有关cookie的详细使用方式,请参考我的博客:
Regarding cookie manipulation in CL_HTTP_CLIENT to avoid CSRF token validation failure issue
https://blogs.sap.com/2017/08/04/regarding-cookie-manipulation-in-cl_http_client-to-avoid-csrf-token-validation-failure-issue/
大家下次如果遇到有关HTTP请求和服务器登录认证的相关问题,不妨按照Jerry本文介绍的方法,通过使用HTTP Watch和Chrome开发者工具,以及查阅SAP帮助文档的方式自行研究,感谢阅读。
ABAP专题