https://raw.githubusercontent.com/ajmaradiaga/feeds/main/scmt/topics/NW-ABAP-Remote-Function-Call-(RFC)-blog-posts.xml SAP Community - NW ABAP Remote Function Call (RFC) 2024-05-20T11:11:17.864383+00:00 python-feedgen NW ABAP Remote Function Call (RFC) blog posts in SAP Community https://community.sap.com/t5/technology-blogs-by-sap/websocket-rfc-rfc-for-the-internet/ba-p/13502531 WebSocket RFC – RFC For the Internet 2021-07-19T13:16:50+02:00 thomas_weiss https://community.sap.com/t5/user/viewprofilepage/user-id/181896 <H3 id="toc-hId-1086515421"><STRONG>Introduction, Overview, and Availability</STRONG></H3><BR /> By using WebSocket as an alternative transport layer for Remote Function Call (RFC), WebSocket RFC, the new web-enabled flavor of RFC, combines the benefits of a standardized transport layer with the well-known advantages of RFC and the benefits of RFC's fast serialization. WebSocket RFC is easy to administrate and is secure by default.<BR /> <H4 id="toc-hId-1019084635"><STRONG>Profit from a New Standardized Transport Layer for RFC</STRONG></H4><BR /> <UL><BR /> <LI>You no longer need a VPN tunnel for RFC connections across network borders, avoid the time-consuming process of setting up a VPN tunnel and the costs entailed by this in terms of time and money required for the respective certificates.</LI><BR /> <LI>Hybrid scenarios are possible without an intermediate SAP Cloud Connector (in this weblog further on, for reasons of simplicity named "Cloud Connector" ).</LI><BR /> <LI>You can use standard HTTPS ports (443) - the normal HTTP port (80) <SPAN style="text-decoration: underline">should not</SPAN> be used because TLS is mandatory for WebSocket RFC as described below -, standard HTTP network infrastructure and tools since WebSocket uses an upgraded HTTPS connection.</LI><BR /> </UL><BR /> In a nutshell, you avoid the disadvantages of the proprietary CPIC protocol so far underlying all RFC communication, and, instead, benefit from a standardized, web-enabled transport layer.<BR /> <H4 id="toc-hId-822571130"><STRONG>Well-known Strengths of RFC</STRONG></H4><BR /> <UL><BR /> <LI>High performance,</LI><BR /> <LI>Tight coupling by usage of a continuously open connection,</LI><BR /> <LI>RFC’s close integration into the ABAP programming model, which is the reason why</LI><BR /> <LI>Exposing a function module for calls from another system or calling a remote-enabled function module (RFM) in another system requires hardly any special knowledge about RFC connectivity on the part of the ABAP developer – no matter if you use RFC over CPIC or over WebSocket.</LI><BR /> </UL><BR /> <H4 id="toc-hId-626057625"><STRONG>Advantages due to Automatic Use of Fast Serialization</STRONG></H4><BR /> <UL><BR /> <LI>Faster by factors than classic serialization and basXML.</LI><BR /> <LI>Transmission speed is equally high for all data and parameter types so that</LI><BR /> <LI>No expert knowledge is required for developing, configuring, and extending high-performing fast RFC scenarios via WebSocket RFC. With fast serialization it is easy to achieve high RFC performance.</LI><BR /> <LI>Fast serialization’s S/4 HANA mode mitigates problems in the RFC transmission caused by incompatible changes of DDIC types with every S/4HANA release.<BR /> (Find more on RFC's fast serialization in my weblog <A href="https://blogs.sap.com/2019/10/28/how-to-profit-from-fast-rfc-serialization/" target="_blank" rel="noopener noreferrer">How to Profit from FAST RFC Serialization</A>)</LI><BR /> </UL><BR /> <H4 id="toc-hId-429544120"><STRONG>Secure by Default</STRONG></H4><BR /> <UL><BR /> <LI>All WebSocket-RFC-connections are TLS-encrypted: WebSocket RFC always uses HTTPS.</LI><BR /> <LI>UCON protection for WebSocket RFC is mandatory and by default active on-premise and in the cloud: You can have different allowlists for the RFMs you expose via CPIC and via WebSocket RFC, which means that you can expose one subset of your system's remote enabled function modules (RFMs) for external access by RFC over CPIC and another subset for external access via WebSocket RFC.</LI><BR /> </UL><BR /> <H4 id="toc-hId-233030615"><STRONG>Supported Authentication Methods</STRONG></H4><BR /> <UL><BR /> <LI>Basic authentication - user/password</LI><BR /> <LI>x.509 - mutual TLS authentication</LI><BR /> <LI>Trusted-trusting (only on-premise)</LI><BR /> </UL><BR /> <H4 id="toc-hId-36517110"><STRONG>Full Support of Queued RFC</STRONG></H4><BR /> WebSocket RFC works fine with t/q/bgRFC.<BR /> <H4 id="toc-hId--159996395"><STRONG>Availability of WebSocket RFC</STRONG></H4><BR /> <UL><BR /> <LI>Delivered as part of<STRONG> SAP S/4HANA 1909</STRONG> with its underlying ABAP Platform and</LI><BR /> <LI>Also available in <STRONG>S/4HANA Cloud and SAP BTP ABAP environment</STRONG>: In SAP BTP ABAP environment, you can create RFMs that can be called from outside (<STRONG>inbound scenario</STRONG>) and you can call RFMs in other systems (<STRONG>outbound scenario</STRONG>). In S/4HANA Cloud inbound and outbound WebSocket RFC scenarios are also possible, if the respective RFMs are part of a Communication Scenario delivered by SAP. As for further details of&nbsp; WebSocket RFC scenarios in the cloud, have a look at the boxed paragraph below "<STRONG>Integration via WebSocket RFC in the cloud"</STRONG><STRONG>. </STRONG></LI><BR /> <LI>Support by RFC-based connectors: So far supported on the client side as of SAP Java Connector 3.1 and on the server side as of SAP Java Connector 3.1.3 and as of NetWeaver RFC SDK 7.50 on client and server side. The implementation of WebSocket RFC is also planned for .NET Connector on client- and server side. So far there is no support for WebSocket RFC in the Cloud Connector.</LI><BR /> </UL><BR /> <H4 id="toc-hId--356509900"><STRONG>Scenarios in Which You Profit Most from WebSocket RFC</STRONG></H4><BR /> <OL><BR /> <LI>You want <U>t</U>o call<STRONG> RFMs across </STRONG>the <STRONG>borders of your company network</STRONG>, e.g. between on-premise systems in different data centers or between your system and the one of your supplier<STRONG> without </STRONG>the tedious <STRONG>process of setting up a VPN tunnel</STRONG>, or you want to <STRONG>expose one group of RFMs to calls from outside of your company network</STRONG> (via WebSocket RFC) and <STRONG>a different group of RFMs to calls from within this network</STRONG> (for which, in general, CPIC-based RFC is used).</LI><BR /> <LI>As for <SPAN style="text-decoration: underline">h</SPAN><U>ybrid connectivity scenarios</U> between an ABAP-based cloud solution and your on-premise system, you can <STRONG>call RFMs in an</STRONG><BR /> <UL><BR /> <LI><STRONG>ABAP-based Cloud</STRONG> solution from an on-premise system via WebSocket RFC <STRONG>without an intermediate Cloud Connector.</STRONG></LI><BR /> <LI><STRONG>On-premise system from an ABAP-based cloud solution without Cloud Connector,</STRONG> but this is <U>only possible, if the respective on-premise system is exposed to the internet</U>. If your on-premise system cannot be reached from the internet, you need Cloud Connector to call RFMs in this system from the cloud. Since the CPIC-based RFC is tunneled via TLS between Cloud Connector and the respective ABAP system in the cloud, CPIC-based RFC suffices for hybrid RFC-scenarios with Cloud Connector. For this reason, Cloud Connector does not support WebSocket RFC in any direction.</LI><BR /> </UL><BR /> </LI><BR /> <LI>Cloud-cloud scenarios: In the cloud, WebSocket RFC <U>enables</U> you to expose RFMs to other SAP cloud products via WebSocket RFC.</LI><BR /> </OL><BR /> <H4 id="toc-hId--553023405"><STRONG>Compatibility of WebSocket RFC and Its Limits</STRONG></H4><BR /> <STRONG>Compatibility</STRONG>: WebSocket RFC is mainly compatible with CPIC RFC - with the exception of these minor restrictions: WebSocket RFC does <STRONG>not</STRONG> support<BR /> <UL><BR /> <LI>RFC callback/the usage of “DESTINATION BACK”,</LI><BR /> <LI>Communication with RFMs that open SAP GUI-based UI/Web GUI (and</LI><BR /> <LI>Forward debugging.</LI><BR /> </UL><BR /> <H4 id="toc-hId--1247254005"><STRONG>Configuration and Test Costs for a WebSocket RFC Scenario</STRONG></H4><BR /> Creating or maintaining a destination for a WebSocket-RFC-connection is little work in itself – both on-premise and in the cloud – for a new scenario, but requires some more effort - mainly in terms of testing -, if you want to use WebSocket RFC in an existing RFC scenario: You need a suitable destination, have to make sure that the RFMs belonging to the respective scenario are on the relevant allowlist of UCON for WebSocket RFC (also cf. section “How to Set up and Maintain UCON Allowlists for WebSocket RFC in More Detail” below) and have to preclude that the RFMs called in your scenario call “DESTINATION 'BACK'” or open an SAP GUI-based UI.<BR /> <H5 id="toc-hId--1737170517"><STRONG>Creation and Configuration of a WebSocket RFC Connection</STRONG></H5><BR /> This is how you get a suitable destination to make an RFC connection over CPIC into a WebSocket RFC scenario or to create a new WebSocket RFC scenario:<BR /> <UL><BR /> <LI>On-premise: An administrator creates and configures a destination for WebSocket RFC – as usual – in transaction SM59. You just need the new type "W". Using a destination of this type in the “CALL FUNCTION” statement you get a WebSocket RFC connection.</LI><BR /> <LI>In the cloud instead of using transaction SM59, creation and maintenance of destinations is done<BR /> <UL><BR /> <LI>In the <U>Communication System</U> in <U>S/4HANA Cloud</U>.</LI><BR /> <LI>In SAP BTP ABAP environment: In the Communication System or in the SAP BTP <U>Destination Service</U></LI><BR /> </UL><BR /> </LI><BR /> </UL><BR /> In <STRONG>SAP BTP ABAP environment</STRONG>, just choose <STRONG>proxy-type “Internet"</STRONG>, in<STRONG> S/4 HANA Cloud “Cloud Connector off”</STRONG>.<BR /> <H5 id="toc-hId--1933684022"><STRONG>Get the Relevant RFM(s) on the UCON Allowlist for WebSocket RFC</STRONG></H5><BR /> The effort to set up the mandatory allowlists for a WebSocket RFC scenario depends on whether the respective RFMs are in the cloud or on-premise and – in on-premise systems – whether it is a new or an existing scenario:<BR /> <UL><BR /> <LI>Exposing an RFM to be called via WebSocket RFC in the cloud requires no additional test effort because all RFMs in the respective Communication Scenario are automatically added to the respective allowlist (cf. below: “Integration via WebSocket RFC in the Cloud”.)</LI><BR /> <LI>In on-premise systems due to mandatory and active-by-default UCON protection for RFMs exposed via WebSocket RFC:<BR /> <UL><BR /> <LI><STRONG>New RFC Scenarios</STRONG> require <U>little effort</U> in this regard because, in these scenarios, it should be known which RFMs need to be exposed.</LI><BR /> <LI>Switching <STRONG>existing RFC scenarios</STRONG> to WebSocket, in general, requires <U>extensive testing</U> because, usually, it will take some time to find out which RFMs need to be exposed in a particular scenario and therefore to be added to the respective UCON allowlist.</LI><BR /> </UL><BR /> </LI><BR /> </UL><BR /> <H5 id="toc-hId--2130197527"><STRONG>Ensure the Relevant RFMs do <SPAN style="text-decoration: underline">Not</SPAN> Use Features Incompatible with WebSocket RFC</STRONG></H5><BR /> Again, less effort is needed, if you want to use WebSocket RFC in a new RFC scenario: In this case, you know the RFMs called by the scenario and it should not be too much work to preclude that the respective RFMs make callbacks or open an SAP-GUI or WEB-GUI-based UI.<BR /> <BR /> As for existing RFC scenarios between different on-premise systems, more testing may be needed before you know which RFMs are called via the respective WebSocket destination and whether these RFMs make callbacks or open an SAP-GUI or WEB-GUI-based UI. Using WebSocket RFC in cases in which hybrid RFC scenarios (between Cloud and on-premise) via Cloud Connector have been used so far, should require less testing because these incompatible features are also not supported by Cloud Connector.<BR /> <BR /> In general, it is a good idea to test things thoroughly if you use WebSocket RFC for an already existing RFC scenario.<BR /> <TABLE style="width: 100%;border-collapse: collapse;border-color: #000000;background-color: #c5d6e3" border="1" cellpadding="5px"><BR /> <TBODY><BR /> <TR><BR /> <TD style="width: 100%"><STRONG>Note</STRONG>: Keep in mind that as with all connectivity features, WebSocket RFC can only be used, if it is supported on the client and server side of a connection.</TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> &nbsp;<BR /> <H4 id="toc-hId--2033308025"><STRONG>No Code Changes Required for Calls via WebSocket RFC</STRONG></H4><BR /> The<STRONG> code to create</STRONG><STRONG>&nbsp;an RFC-call is the same no matter whether WebSocket or CPIC</STRONG> is the underlying transport layer. Just use the good old “CALL FUNCTION” statement also for WebSocket RFC: In all supported RFC scenarios – that is all scenarios except for those using RFC callback or opening an SAP-GUI or WEB-GUI-based UI – you can use WebSocket RFC instead of RFC over CPIC. No need not change the “CALL FUNCTION” statement in any way: All you need is a <STRONG>destination of type “W</STRONG>”. And, of course, you should make sure that the RFMs called via WebSocket RFC do not use "DESTINATION BACK" or open an SAP-GUI or WEB-GUI-based UI.<BR /> <H4 id="toc-hId-2065145766"><STRONG>No Particular Connectivity Knowledge Required by Developers for WebSocket-RFC-Calls</STRONG></H4><BR /> While usage of other HTTP-based connectivity technologies may require a developer to have some complex knowledge of the respective technology, developers using <STRONG>WebSocket</STRONG> RFC get along with the limited knowledge required to set up an RFC call. WebSocket RFC does <STRONG><SPAN style="text-decoration: underline">not</SPAN> require the creation of a particular proxy or a detailed understanding of how things are serialized.</STRONG>&nbsp;The complete WebSocket handling is transparent in a lower layer and developers and administrators need not care about it.<BR /> <TABLE style="width: 100%;border-style: solid;border-color: #000000;background-color: #c5d6e3" width="100%" cellpadding="10ptb"><BR /> <TBODY><BR /> <TR><BR /> <TD width="100%"><BR /> <H3 id="toc-hId--2132932028"><STRONG>Integration via WebSocket RFC in the cloud</STRONG></H3><BR /> As for <U>all</U> connections with other systems in ABAP-based clouds,<BR /> <BR /> (1) <U>Inbound</U> WebSocket RFC scenarios need:<BR /> <UL><BR /> <LI>A dedicated <U>Communication scenario</U> that defines all RFMs to be called on the server side (inbound scenario) and</LI><BR /> <LI>The <U>Instantiation of this Communication Scenario</U> in form of a <U>Communication Arrangement</U> with a <U>Communication System</U> and a<U> Communication User</U> (cf. <A href="https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/1decd8b8747443ee8839ce4474a3643e.html" target="_blank" rel="noopener noreferrer">related documentation</A> and <A href="https://developers.sap.com/tutorials/abap-environment-communication-arrangement.html" target="_blank" rel="noopener noreferrer">tutorial</A> for SAP BTP ABAP environment).</LI><BR /> </UL><BR /> (2) <U>Outbound</U> WebSocket RFC scenarios offer two options. You can<BR /> <UL><BR /> <LI>Instantiate the respective <U>Communication Scenario</U> (as described above under item 1) or</LI><BR /> <LI>Make do <U>without a Communication Scenario</U> and simply use a reference to the respective <U>destination in the SAP BTP Destination Service</U>&nbsp;in your ABAP Code. (cf. <A href="https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/bbbd14283e984d6aa7b05062f197ef5b.html" target="_blank" rel="noopener noreferrer">related documentation</A>)</LI><BR /> </UL><BR /> All this, by and large, is the <SPAN style="text-decoration: underline">sa</SPAN><SPAN style="font-family: inherit;font-size: inherit"><SPAN style="text-decoration: underline">me for all types of communication in the cloud</SPAN> between different systems: </SPAN><SPAN style="font-family: inherit;font-size: inherit">WebSocket RFC scenarios do </SPAN><U style="font-family: inherit;font-size: inherit">not</U><SPAN style="font-family: inherit;font-size: inherit"> differ in any principal way from scenarios based on RFC via CPIC or HTTP in the cloud. But there is a basic difference as to&nbsp;</SPAN><BR /> <UL><BR /> <LI>Whether a business or technical scenario is delivered by SAP, in which case SAP develops the respective Communication Scenario and you as customer only configure/instantiate it,</LI><BR /> </UL><BR /> or<BR /> <UL><BR /> <LI>Whether something is developed by the customer, in which case the customer first needs to create the relevant Communication Scenario (if one is needed) before configuring it.</LI><BR /> </UL><BR /> </TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> &nbsp;<BR /> <TABLE style="background-color: #d3d3d3;width: 100%;border-color: #d62727;border-style: solid" width="100%" cellpadding="5px"><BR /> <TBODY><BR /> <TR style="height: 41px"><BR /> <TD style="height: 41px" width="465"><STRONG>Important Note: </STRONG>Before enabling a WebSocket RFC scenario, make sure that all RFMs to be called over WebSocket do not open any SAP-GUI or WEB-GUI-based UIs or make callbacks. Often, this will require extensive testing.</TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> &nbsp;<BR /> <H4 id="toc-hId-1672118756"><STRONG>The Different Layers of WebSocket RFC and CPIC RFC</STRONG></H4><BR /> Basically, WebSocket RFC differs from CPIC RFC by having a different transport layer and mandatory fast serialization, while you call an RFM via WebSocket RFC just the way you are used to as an ABAP developer:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2021/06/WebSocket_RFC_2.png" /></P><BR /> &nbsp;<BR /> <H3 id="toc-hId-1769008258"><STRONG>WebSocket RFC in More Detail</STRONG></H3><BR /> <H4 id="toc-hId-1279091746"><STRONG>High Performance and Compression</STRONG></H4><BR /> WebSocket-RFC’s permanent use of fast serialization achieves a much higher data compression than classic serialization and basXML, which is partially due to it using different compressions for LAN and WAN scenarios:<BR /> <UL><BR /> <LI>In WAN, a high compression rate is most important to reach a high performance and to minimize network bandwidth costs. This is why, in WAN scenarios, fast serialization uses a compression algorithm with a high compression rate and, to some degree, ignores the time needed for the data compression.</LI><BR /> <LI>In LAN, fast serialization uses a compression with a good balance between payload reduction and the time needed to process the compression algorithm – because in LAN compression speed and compression rate are equally important.</LI><BR /> </UL><BR /> WebSocket RFC automatically selects the best compression for your RFC scenario because it measures the latency of the respective connection during the TLS handshake and, based on this measurement, decides, if LAN or WAN compression is better. Still, you can override this automatic selection and chose to always use the high WAN compression, if – for example – you primarily want to save bandwidth because you are in a cloud scenario and may have to pay for bandwidth.<BR /> <BR /> Note: Automatic selection of the best compression is only available for connections between two ABAP servers and not supported by the RFC-based connectors.<BR /> <BR /> Note: By default, the line between LAN and WAN is 110 ms, but you can adapt this to your specific needs.<BR /> <H4 id="toc-hId-1250761932"><STRONG>Latest Supported Version of WebSocket RFC Used Automatically</STRONG></H4><BR /> The WebSocket handshake exchanges protocol information so that always the highest version of WebSocket RFC is used that is supported both by client and server. There is no need to select and maintain this version manually in transaction SM59.<BR /> <H4 id="toc-hId-1054248427"><STRONG>Extensibility of RFC Parameters and Incompatibilities Due to Field-Extensions in S/4</STRONG></H4><BR /> Due to WebSocket RFC's use of fast serialization, incompatibilities between structures on the client side and structures on the server side are detected. If possible without data loss, the data is automatically transferred to the server-side structures, otherwise - if data loss within a particular component cannot be avoided due to incompatibility between parameter-types on client- and server-side - an error message is thrown: This mitigates many of the problems caused by incompatible changes of DDIC types with every new S/4 release. Fast serialization allows for field extensions or the introduction of new fields at all positions in structures used in interfaces of existing function modules, which has the consequence that fields that do not exist on both sides are omitted in the data transmission, and no error message is thrown in this case.<BR /> <H4 id="toc-hId-857734922">Web Socket RFC's Flavor of Fast Serialization Supports Transparence and Maximal Parameter Extensibility</H4><BR /> Just as ABAP Objects – compared to procedural ABAP – offers more and less at the same time, namely &nbsp;more powerful object-oriented features and a stricter syntax check, which forbids many old statements,&nbsp; WebSocket RFC’s mandatory use of fast serialization’s future-proof interface contract for new scenarios is more powerful in terms of&nbsp; parameter extensibility and, also at the same time, forbids non-transparent parameter mapping mechanisms used in exceptional situations - most times in scenarios connecting newer with very old releases -&nbsp; by the other RFC serializations. WebSocket RFC’s flavor of fast serialization<BR /> <UL><BR /> <LI>Offers you maximal extensibility of structures and tables, namely at all positions, not only at the end, and</LI><BR /> <LI>Strictly forbids extreme differences in technical properties of the same RFC parameter between client- and server side, which often are tolerated by classic serialization or basXML and handled by unexpected exceptional mapping mechanisms. While fast serialization for CPIC-based RFC also has these modes that, to a large degree, emulate these exceptional mapping mechanisms of the other RFC serializations, WebSocket RFC does not offer fast serialization's emulation/compatibility modes for basXML and classic serialization. Instead WebSocket RFC's mandatory usage of fast serialization's future-proof interface contract for new scenarios enforces a transparent and consistent behavior as to which differences in the same RFC parameter between client- and server side are tolerated, and which differences lead to an error. (Find out more on fast serializations different flavors or modes in my weblog <A href="https://blogs.sap.com/2019/10/28/how-to-profit-from-fast-rfc-serialization/" target="_blank" rel="noopener noreferrer">How to Profit from FAST RFC Serialization</A> in the section on configuration.)</LI><BR /> </UL><BR /> <H4 id="toc-hId-661221417"><STRONG>Support for Multiplexing and Load Balancing</STRONG></H4><BR /> <STRONG>Multiplexing</STRONG> for WebSocket RFC means that a physical WebSocket <SPAN style="font-size: 1rem">connection/tunnel is only created once between two points and can be re-used for other RFC connections via WebSocket between these two points. Given this re-use of a WebSocket tunnel, the fact that WebSocket protocol and TLS need several handshakes to setup a connection only has a small impact on the performance of WebSocket RFC. There is also <STRONG>support for load balancing</STRONG> by Web Socket RFC. </SPAN><BR /> <BR /> <SPAN style="font-size: 1rem">Still, multiplexing and load balancing have some restrictions and presuppositions as explained in the table below:&nbsp;</SPAN><BR /> <TABLE style="width: 106.983%;border-collapse: collapse" border="1" cellspacing="30" cellpadding="5"><BR /> <TBODY><BR /> <TR style="height: 27px"><BR /> <TD style="width: 21.562%;height: 27px"></TD><BR /> <TD style="width: 38.3035%;height: 27px"><STRONG>ABAP System – ABAP System</STRONG></TD><BR /> <TD style="width: 47.1174%;height: 27px"><STRONG>ABAP-based Connector/NW RFClib – ABAP System</STRONG></TD><BR /> </TR><BR /> <TR style="height: 27px"><BR /> <TD style="width: 21.562%;height: 27px"><STRONG>Load Balancing</STRONG></TD><BR /> <TD style="width: 38.3035%;height: 27px">Only with SAP Web Dispatcher.</TD><BR /> <TD style="width: 47.1174%;height: 27px">Standard HTTP(S) load balancer will also do.</TD><BR /> </TR><BR /> <TR style="height: 83px"><BR /> <TD style="width: 21.562%;height: 83px"><STRONG>Multiplexing</STRONG></TD><BR /> <TD style="width: 38.3035%;height: 83px">Only with Web Dispatcher and if HTTP/2 is supported by all infrastructure in between client and server.</TD><BR /> <TD style="width: 47.1174%;height: 83px">Not possible due to missing HTTP/2 support by connectors, but this is remedied by connectors' pooling of unused RFC connections (both for RFC over CPIC and WebSocket) that enables re-use of RFC connections.</TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> &nbsp;<BR /> <H4 id="toc-hId-464707912"><STRONG>How to Set up and Maintain UCON Allowlists for WebSocket RFC in More Detail</STRONG></H4><BR /> As you already know, in the cloud, all RFMs to be exposed by WebSocket RFC (inbound scenario) need to be listed in a Communication Scenario. Then all these RFMs are automatically added to the UCON allowlist for WebSocket RFC once the respective Communication Scenario is activated. (The same is true for RFMs to be called via CPIC RFC: The respective UCON allowlist is automatically maintained based on the RFMs listed in the relevant Communication Scenarios.)<BR /> <BR /> On-premise, for the usage of WebSocket RFC, there is a new UCON scenario that is mandatory and active by default. Now you have UCON RFC basic (for calls via CPIC) and UCON for WebSocket RFC with different allowlists for RFMs to be exposed via CPIC and via WebSocket. In on-premise systems, you must fill the respective allowlists manually, while – as you know by now - in the Cloud, all called RFMs for incoming calls (inbound scenarios) are defined in the Communication Scenario, and then automatically added to the respective UCON allowlist.<BR /> <BR /> Exposing RFMs to calls via CPIC from within your company’s network is less risky than exposing RFM to calls over WebSocket from the internet. Therefore, you should keep the numbers of RFMs exposed to calls via WebSocket RFC as small as possible, and this is why UCON for WebSocket RFC has a dedicated allowlist of its own that you should maintain carefully: It&nbsp; would be very insecure, if you exposed all RFMs you need to access in your CPIC-based RFC scenarios also for external calls over WebSocket – as it would be the case if you had a shared allowlist for RFC over CPIC and WebSocket RFC. For security reasons, you <U>should</U> have an allowlist of its own for WebSocket-RFC-scenarios, if your ABAP onPremise system is exposed to the internet<BR /> <BR /> It is, however, possible to select an option in UCON for WebSocket RFC that automatically exposes the same RFMs via WebSocket RFC and via RFC over CPIC. This option is mainly meant for those customers who can or want to invest as little time as possible in the UCON protection of their server-side WebSocket RFC communication and, still, want to profit from UCON protection of WebSocket RFC. But of course, having distinct allowlists for WebSocket RFC and CPIC RFC respectively, is more secure.<BR /> <TABLE style="width: 100%;border-collapse: collapse;background-color: #d3d3d3;border-color: #d62727" border="1" cellpadding="5px"><BR /> <TBODY><BR /> <TR><BR /> <TD style="width: 100%"><BR /> <BR /> <STRONG>Important Note:&nbsp;</STRONG>No matter whether you chose to have the same or different allowlists for RFMs to be called over WebSocket and over CPIC, - as already stated above - you should only enable WebSocket RFC for a particular destination based on an intentional decision and after extensive testing:<BR /> <BR /> Before you have to make sure that no SAP-/WEBGUIs and no callbacks are used in the RFMs called via the respective destination: Since these features are not supported in WebSocket RFC, calling RFMs that open SAP-/WEBGUI-based UIs or use callbacks over WebSocket will cause a dump, which should be prevented by testing.</TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> Administration of UCON for WebSocket requires little effort because - in contrast to UCON RFC basis for CPIC-based RFC - there is no dedicated logging and there are no phases in UCON for WebSocket RFC. You simply do not need this: Due to the extensive testing that is required for WebSocket RFC scenarios, you know exactly which RFMs to expose. Still, if you chose to have the same allowlist for both RFC flavors, accordingly, the UCON phase tool of the UCON RFC basic scenario shows all RFC calls in the same way no matter if they are WebSocket- or CPIC-based.<BR /> <H3 id="toc-hId-561597414"><STRONG>Summary</STRONG></H3><BR /> Gone are the days, when you had to choose between RFC and a connectivity technology with a standardized web-enabled transport layer. With WebSocket RFC you have it all: The advantages of a standardized transport layer and the well-known advantages of RFC. Calling RFMs via WebSocket RFC you can use standard internet infrastructure and no longer need VPN tunnels for calls across the borders of your business network. Still you get RFC’s high performance, a continuously open connection and RFC’s close integration into the ABAP programming model plus all the improvements that come with RFC’s fast serialization - such as its equally high transmission speed for all data and parameter types as well as for all permitted parameter extensions and fast serialization’s S/4HANA mode that mitigates problems in the RFC transmission caused by incompatible changes of DDIC types with every S/4HANA release.<BR /> <BR /> The RFC statement you need for calls via Web Socket RFC is the same as it ever was. But at any rate, you should take into account that WebSocket RFC does not support SAP-/WEBGUI-based UIs or RFC callbacks.<BR /> <BR /> WebSocket RFC is secure by default because of mandatory TLS-encryption and mandatory and active-by-default UCON protection on-premise and in the cloud. The test effort needed to setup the respective allowlist with all relevant RFMs varies depending on whether the RFMs to be exposed are known or not: No additional effort to fill the UCON list is required in the cloud and for new on-premise scenarios. Using WebSocket RFC for existing on-premise scenarios may need extensive testing to find out the respective RFMs you need to expose.<BR /> <BR /> All in all, with WebSocket RFC you get a lot of advantages with comparatively little effort.<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp; 2021-07-19T13:16:50+02:00 https://community.sap.com/t5/technology-blogs-by-members/async-parallel-abap-in-a-oo-way/ba-p/13509594 ASYNC/Parallel ABAP in a OO way 2021-08-26T17:29:46+02:00 felipe_dimmu23 https://community.sap.com/t5/user/viewprofilepage/user-id/620841 <H2 id="toc-hId-957641428">Edit:</H2><BR /> After some feedback and some time to work on this I've improved the examples and introduced the Thread Pool Executor concept.<BR /> <H1 id="toc-hId-632045204">Motivation</H1><BR /> Every now and then we find a need for doing some work in parallel. Recently I’ve worked on a process that was taking far too long to be of any use. It was taking large amounts of data in and creating an even larger amount of records given complex rules, validations and enrichment.<BR /> <BR /> Refreshing some ABAP parallelism techniques, my options were basically to split the input data and then running FMs&nbsp;<EM>in background,</EM>&nbsp;<EM>starting a new task</EM>&nbsp;or&nbsp;<EM>writing a report and scheduling a job</EM>&nbsp;with parallelism being ranges of a selection criteria.<BR /> <BR /> All valid options, I suppose, but I got used to work purely in OO and hammering FMs here and there to have my parallelism had a particular&nbsp;<EM>bad&nbsp;</EM>smell.&nbsp; It would prevent me to assert some critical behavior via unit tests, for starters, and it would also add this new responsibility, running in parallel, to weird places with code that looked boring and repetitive (take data from classes, run fm, take data back…).<BR /> <BR /> So I decided to find an OO approach to parallelism in ABAP, and took Java Thread as inspiration. I was particularly drawn to Java Thread&nbsp; given its simple&nbsp;<EM>Runnable&nbsp;</EM>interface, which allows developers to quickly wrap what needs to be done in parallel in a single method. I could use it to simply call the existing methods I already had. Below is an example on how it would look like in Java.<BR /> <PRE class="language-java"><CODE> public class MyRunnable implements Runnable {<BR /> <BR /> public void run(){<BR /> myOtherClassMethodThatDoesStuff( )<BR /> }<BR /> }<BR /> <BR /> Runnable runnable = new MyRunnable(); // or an anonymous class, or lambda...<BR /> Thread thread = new Thread(runnable);<BR /> thread.start();</CODE></PRE><BR /> <H1 id="toc-hId-435531699">zthread</H1><BR /> There are probably hundreds of similar implementations to this out there. Hope this one can be useful for some of you. My concept is exactly the same as in Java, having the Runnable interface and the Thread as the starting point.&nbsp; As I’m used to (and like) the callback idea behind Javascript, I’ve thrown it into to mix. It made some of the code I needed easier to write and test. It looks something like this:<BR /> <H6 style="overflow: hidden;margin-bottom: 0px" id="toc-hId-884431789"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2021/08/thread_full.png" /></H6><BR /> <H6 id="toc-hId-687918284">Created with PlantUML(<A href="http://plantuml.com" target="_blank" rel="nofollow noopener noreferrer">http://plantuml.com</A>)</H6><BR /> There is a thread factory interface and some default implementations too, which I've discarded from the diagram, to help unit test classes using Threads.<BR /> <H1 id="toc-hId--154008816">Usage</H1><BR /> You can check git for the most up to date documentation. I´m putting some examples here to show how to use it in general.<BR /> <BR /> The examples below are building up from previous examples. So zc_my_runnable is not always declared and its implementation is the one from its last time defined.<BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId--221439602">Raw way</H2><BR /> Simply implement your runnable interface, give it to a Thread and start it. The drawback of this is that is up to the caller to manage how many Threads can run in parallel, and implement logic wait for Threads to finish so others can start and so forth.<BR /> <BR /> If your program will have 2 or 3 threads that is ok and this way suits you.&nbsp; But if you are splitting large data into smaller parts, if it ends up 100 smaller parts this will consume all of your system resources.<BR /> <BR /> Always prefer using a Pool Executor like in the next section below.<BR /> <PRE class="language-abap"><CODE>"example have merged definition and implementation<BR /> class zcl_my_runnable definition.<BR /> public section.<BR /> interfaces zif_runnable. <BR /> <BR /> method constructor.<BR /> "store data to process async/paralel.<BR /> endmethod.<BR /> <BR /> method zif_runnable~run.<BR /> "process data<BR /> endmethod.<BR /> <BR /> endclass.<BR /> <BR /> data(runnable1) = new zcl_my_runable( datasplit1 ).<BR /> data(runnable2) = new zcl_my_runable( datasplit2 ).<BR /> <BR /> new zcl_thread( runnable1 )-&gt;start( ).<BR /> new zcl_thread( runnable2 )-&gt;start( ).<BR /> <BR /> zcl_thread=&gt;join_all( ). "awaits all threads to finish</CODE></PRE><BR /> &nbsp;<BR /> <H2 id="toc-hId--417953107">Thread pool executor</H2><BR /> The thread pool executor is an executor service that allows to limit the number of threads that can run in parallel based on its pool size, allowing to work to be forked indefinitely without consuming all system resources. Java has several executor services implementations, I’m delivering a basic one that can be extended as seem fit.<BR /> <BR /> The runnable interface implementation is the same as the previous example.<BR /> <PRE class="language-abap"><CODE>"only 10 will be allowed in parallel in the pool<BR /> data(executor) = zcl_executors=&gt;new_fixed_thread_pool( 10 ). <BR /> <BR /> data(runnable1) = new zcl_my_runnable( datasplit1 ).<BR /> data(runnable2) = new zcl_my_runnable( datasplit2 ).<BR /> <BR /> "submits individual runnables<BR /> executor-&gt;submit( runnable1 ).<BR /> executor-&gt;submit( runnable2 ).<BR /> <BR /> "Asks for a 100 runnables to run but, <BR /> "due to the pool size only 10 will<BR /> "be allowed to be active at a time<BR /> executor-&gt;invoke_all( a100Runnables ). <BR /> <BR /> "blocks executor from queing new runnables<BR /> executor-&gt;shutdown( ).<BR /> <BR /> "awaits threads to finish and queue to be empty<BR /> executor-&gt;await_termination( ).<BR /> </CODE></PRE><BR /> &nbsp;<BR /> <H1 id="toc-hId--743549331">Retrieving results</H1><BR /> You can get the result of your threads in multiple ways, but all require that your&nbsp;<EM>result</EM>&nbsp;be class implementing the&nbsp;<EM>zif_runnable_result</EM>&nbsp;interface.<BR /> <BR /> Ideally, you want your results to be separate objects, as it should be significantly smaller than your runnable in terms of data size and this plays a role in resource consumption and the serialization process behind threads.<BR /> <BR /> In the example below, however, we are implementing it in the runnable itself.<BR /> <PRE class="language-abap"><CODE>class zcl_my_runnable definition.<BR /> public section.<BR /> interfaces zif_runnable,zif_runnable_result. <BR /> data: my_result type i. <BR /> methods:<BR /> construtor<BR /> importing<BR /> numbers type any table. <BR /> get_sum returning value(rv_result) type i.<BR /> <BR /> method zif_runnable~run.<BR /> my_result = reduce #( init result = 0<BR /> for number in numbers<BR /> next result = result + number ). <BR /> ro_result = me. "important!<BR /> endmethod.<BR /> <BR /> method get_sum.<BR /> rv_result = my_result.<BR /> endmethod.<BR /> <BR /> endclass.</CODE></PRE><BR /> &nbsp;<BR /> <H2 id="toc-hId--810980117">From Threads</H2><BR /> If you are creating your threads manually, the result will come from the Thread get_result( ) method. If this method is called before finished, zcx_still_running is raised. You can check the thread was successful with get_error( ).<BR /> <PRE class="language-abap"><CODE>data(runnable1) = new zcl_my_runnable( value #( ( 10 ) ( 10 ) ( 10 ) ). "30<BR /> data(runnable12) = new zcl_my_runnable( value #( ( 20 ) ( 20 ) ( 20 ) ). "60<BR /> <BR /> data(thread) = new zcl_thread( runnable1 ). <BR /> data(thread2) = new zcl_thread( runnable2 ).<BR /> <BR /> thread-&gt;start( ).<BR /> thread2-&gt;start( ).<BR /> <BR /> zcl_thread=&gt;join_all( ).<BR /> <BR /> data(result) = cast zcl_my_runnable( thread-&gt;get_result( ) )-&gt;get_sum( ).<BR /> data(result2) = cast zcl_my_runnable( thread2-&gt;get_result( ) )-&gt;get_sum( ).<BR /> <BR /> data(total) = result + result2.<BR /> write: total. "90</CODE></PRE><BR /> &nbsp;<BR /> <H2 id="toc-hId--660239265">From Executors</H2><BR /> Executors don’t return the Threads created, but rather a&nbsp;<EM>Future</EM> representing that Thread result. When asking the <EM>Future</EM> for its result, it will wait for the termination of its Thread if it is still running. Therefore the following code is synchronous but runs in parallel (different session). If an error happens during the runnable execution, the Future will raise zcx_thread_execution with the error as its previous exception.<BR /> <PRE class="language-abap"><CODE>executor-&gt;submit( runnable1 )-&gt;get( ).</CODE></PRE><BR /> For actual async and parallel code to execute, wait for the executor to terminate.<BR /> <PRE class="language-abap"><CODE>"for submits<BR /> data(future) = executor-&gt;submit( runnable1 ).<BR /> data(future2) = executor-&gt;submit( runnable2 ).<BR /> executor-&gt;shutdown( ).<BR /> executor-&gt;await_termination( ).<BR /> <BR /> data(result) = cast zcl_my_runnable( future-&gt;get( ) )-&gt;get_sum( ). "30 from last example<BR /> data(result2) = cast zcl_my_runnable( future2-&gt;get( ) )-&gt;get_sum( ). "60 from last example<BR /> <BR /> write: result + result2. "90<BR /> <BR /> "same for invoke_all<BR /> data(futures) = executor-&gt;invoke_all( value#( ( runnable1 ) ( runnable2 ) ).<BR /> executor-&gt;shutdown( ).<BR /> executor-&gt;await_termination( ).<BR /> <BR /> loop at futures into data(future).<BR /> total = total + cast zcl_my_runnable( future-&gt;get( ) )-&gt;get_sum( ).<BR /> endloop.<BR /> <BR /> write: total. "90</CODE></PRE><BR /> &nbsp;<BR /> <H1 id="toc-hId--563349763">Callbacks</H1><BR /> Callbacks are my preferable way to manage async/parallel work. It is a simple concept to understand and it allows decoupling the code responsible for <EM>defining work</EM> from the code responsible for <EM>processing results</EM>.<BR /> <BR /> Simply implement the <EM>zif_thread_callback</EM> interface and give it to Threads or Executors and use its <EM>on_result</EM> to collect, merge or aknowledge results as you please.<BR /> <BR /> The callback object must have a valid reference throughout the lifecycle of the Threads.<BR /> <PRE class="language-abap"><CODE>class zcl_sum_callback definition.<BR /> <BR /> public section.<BR /> interfaces zif_thread_callback.<BR /> methods:<BR /> get_total returning value(rv_result) type i.<BR /> private section.<BR /> data: my_total type i.<BR /> <BR /> <BR /> method zif_thread_callback~on_result.<BR /> "be safe<BR /> check io_result is instance of zcl_my_runnable. <BR /> data(result) = cast zcl_my_runnable( io_result ).<BR /> my_total = my_total + result-&gt;get_sum( ). <BR /> endmethod.<BR /> <BR /> method zif_thread_callback~on_error.<BR /> "this method is triggered in case any error happen during runnable execution.<BR /> "you can raise your own exceptions there as well<BR /> "taskname is available in both on_callback and on_error.<BR /> "taskname is an optional value of thread constructor<BR /> raise exception type zcx_my_calculation_error<BR /> exporting<BR /> previous = io_error<BR /> taskname = iv_taskname.<BR /> <BR /> endmethod.<BR /> <BR /> method get_total.<BR /> rv_result = my_total.<BR /> endmethod.<BR /> <BR /> endclass.<BR /> <BR /> data(callback) = new zcl_sum_callback( ).<BR /> <BR /> "giving it to threads<BR /> new zcl_thread( <BR /> io_runnable = runnable1<BR /> io_callback = callback )-&gt;start( ). "sum to 30<BR /> <BR /> <BR /> "giving it to executor<BR /> data(executor) = zcl_executors=&gt;new_fixed_thread_pool(<BR /> iv_threads = 10<BR /> io_callback = callback ).<BR /> <BR /> executor-&gt;submit( runnable2 ). "sum to 60<BR /> executor-&gt;await_termination( ).<BR /> <BR /> data(result) = callback-&gt;get_total( ).<BR /> <BR /> write: result. "90</CODE></PRE><BR /> &nbsp;<BR /> <H1 id="toc-hId--759863268">Some thoughts</H1><BR /> Feel free to check the code behind it. What is happening is the serialization of the runnable so it can be sent to a function module as a string. This FM is called using options <EM>starting new task&nbsp;</EM>and&nbsp;<EM>on end of task</EM>. In the FM, the runnable is deserialized and its&nbsp;<EM>run&nbsp;</EM>method is called. Whatever result or error that happen are serialized by the FM and deserialized back by the Thread class. If a callback routine is defined, it is called with the result or error. This means a couple of things.<BR /> <UL><BR /> <LI>Avoid complex runnables, all serialization constrains of the&nbsp;<EM>id</EM>&nbsp;transformation are applicable. If you have complex runnables, relying on other objects, prefer instantiating those objects inside the&nbsp;<EM>run&nbsp;</EM>method.</LI><BR /> <LI>Parallel work runs on&nbsp;<EM>dialog workers.&nbsp;</EM>As far as I can tell, the only restrictions are memory allocation and time execution (5 min being default). Make sure you split into chuncks that fit dialog workers restrictions.</LI><BR /> <LI>Each Thread runs on a different session, on top of serialized/deserialized objects, so…Don’t fall into the trap of expecting a singleton to be shared between threads.</LI><BR /> <LI>If you have a server with 2 processors, it doesn’t matter if you have 20 threads as they will just&nbsp;<EM>round robin&nbsp;</EM>your CPU time. Most production servers have a good enough number of threads available, but it is not always the case for development servers. Make sure you account for this when developing, testing, deploying.</LI><BR /> <LI>Threads can´t be stopped. Unfortunately I did not found a way to get the PID of a thread based on this task name.</LI><BR /> <LI>If a callback routine is defined, it must still be a valid reference at the end of the Thread.</LI><BR /> </UL><BR /> SAP does have something in newer versions, check the comments about cl_abap_parallel. I think overall we still need some other tools to allow an raw OO implementation to the <EM>philosopher’s dinner </EM>problem.<BR /> <BR /> But, as I say this I also realize we are moving away from heavy process and relying on more stream like flows with small API endpoints. In any case, this is still a tool that can be used when needed.<BR /> <BR /> Cheers and enjoy!<BR /> <H2 id="toc-hId--1249779780">Git repository&nbsp;<A href="https://github.com/xinitrc86/zthread" target="_blank" rel="noopener nofollow noreferrer">here</A>.</H2> 2021-08-26T17:29:46+02:00 https://community.sap.com/t5/technology-blogs-by-sap/configure-sap-event-mesh-for-sap-s-4hana-on-premise/ba-p/13528833 Configure SAP Event Mesh for SAP S/4HANA On-Premise 2022-01-19T16:46:31+01:00 former_member264217 https://community.sap.com/t5/user/viewprofilepage/user-id/264217 <H4 id="toc-hId-1217626813"><STRONG>Introduction</STRONG></H4><BR /> This blog post will guide you through steps to use SAP Event Mesh in SAP BTP, Cloud Foundry environment and to establish connection between SAP Event Mesh and SAP S/4HANA (on premise) for asynchronous data transfer.<BR /> <BR /> Blog will cover introduction, architecture, enabling SAP Event Mesh and configuration of Message Queues on SAP BTP. We will learn to establish connection between SAP Event Mesh service and SAP S/4 HANA (on premise) system. Then will have a short demo of data transfer between these systems.<BR /> <H4 id="toc-hId-1021113308"><STRONG>SAP Event Mesh</STRONG></H4><BR /> SAP Event Mesh (Earlier known as SAP Enterprise Messaging) is a fully managed cloud service to offer messaging in SAP Business Technology Platform (SAP BTP). This service allows real-time and asynchronous communication between applications through events to develop responsive applications. So these applications can work independently and connect seamlessly through decoupled communication.<BR /> <BR /> <STRONG>Note:</STRONG> SAP Event Mesh is available in SAP BTP, Cloud Foundry environment.<BR /> <BR /> <STRONG>Architecture</STRONG><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-17-at-2.08.09-AM.png" /><BR /> <H4 id="toc-hId-824599803"><STRONG>Steps</STRONG></H4><BR /> <UL><BR /> <LI>Enablement of SAP Event Mesh service on SAP Business Technical Platform</LI><BR /> <LI>Configuration of Message Queue in SAP Event Mesh cockpit</LI><BR /> <LI>Test SAP Event Mesh service using Postman Application</LI><BR /> <LI>Setup Connection between SAP Event Mesh service and SAP S/4 HANA (on premise) system through RFC Destination and OAuth Client Profile</LI><BR /> <LI>Demo of data access in SAP S/4HANA (on premise) system</LI><BR /> </UL><BR /> <STRONG>Enablement of SAP Event Mesh Service on SAP Business Technical Platform:-</STRONG><BR /> <BR /> Open&nbsp;<A href="https://account.hana.ondemand.com/" target="_blank" rel="noopener nofollow noreferrer">SAP Business Technical Platform</A>&nbsp;and register yourself, if you have already registered then logon with your user credential.<BR /> For SAP Event Mesh service, user can use trial account also by clicking on <STRONG>Go To Your Trial Account</STRONG>.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-17-at-2.27.38-AM.png" />A new trial global account will be created with sub-account <STRONG>trial</STRONG>. Click on sub-account. User can see sub-account specifications(Id, Tenant Id, SubDomain etc.), Cloud Foundry environment, Entitlements (Subscribed services) etc.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-6.01.24-PM.png" /><BR /> <BR /> Click on <STRONG>Create Space</STRONG> button. Provide Space name as '<STRONG>emtrial'</STRONG> and press <STRONG>Create</STRONG>. User can see newly created Space '<STRONG>emtrial'</STRONG> under <STRONG>trial</STRONG> sub-account.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-6.04.05-PM.png" />Click on created Space. It will navigate to that space. You can see <STRONG>‘Service’</STRONG> tab in left side of page. This tab is having 2 sections – <STRONG>Service Marketplace</STRONG> (SAP provided services for which user has taken subscription),&nbsp;<STRONG>Instances</STRONG> (Instances created by user).<BR /> <BR /> Click on <STRONG>Service Marketplace </STRONG>tab. Search for <STRONG>Event Mesh </STRONG>service. User can see Documentation and available service plan for Event Mesh through clicking on tile.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-6.06.31-PM.png" />Click on <STRONG>Create</STRONG> button to create a new instance of Event Mesh service. Provide details as below and click on <STRONG>Create </STRONG>button in popup<STRONG>.</STRONG><BR /> <BR /> Basic Info:-<BR /> Service - <STRONG>Event Mesh</STRONG><BR /> Plan.- <STRONG>dev </STRONG>(for trial)<BR /> Instance Name - <STRONG>eminstance</STRONG><BR /> Parameters:-<STRONG> {"emname": "emdemo", "options":{"management": true, "messagingrest": true}}</STRONG><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-17-at-3.03.29-AM.png" /><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-17-at-3.03.39-AM.png" />User can see newly created instance under <STRONG>Services-&gt;Instances </STRONG>in left side of page.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-6.25.44-PM.png" /><SPAN style="font-size: 1rem">Click on </SPAN><STRONG style="font-size: 1rem">Create Service Key </STRONG><SPAN style="font-size: 1rem">to generate service key for Event Mesh instance. Provide Service Key Name as '<STRONG>emservicekey' </STRONG>and click on <STRONG>Create</STRONG> button.</SPAN><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-6.26.14-PM.png" />New Service Key will be created which will be bound to service instance. Service key will be used to access SAP Event Mesh Service by external systems.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-6.27.55-PM.png" />Click on <STRONG>View</STRONG> button. A popup will appear and user can see <STRONG>Credentials</STRONG> to access SAP Event Mesh service. Note down <STRONG>clientid</STRONG>, <STRONG>clientsecret</STRONG>, <STRONG>tokenendpoint</STRONG> and <STRONG>uri</STRONG> which will be required later on. You can download credentials in text format as well.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-6.28.32-PM.png" /><SPAN style="font-size: 1rem">Click on <STRONG>View Dashboard</STRONG></SPAN> button for instance <STRONG>eminstance.&nbsp;</STRONG><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-6.32.53-PM.png" /></P><BR /> &nbsp;<BR /> <BR /> <STRONG>Configuration of Message Queue in SAP Event Mesh Cockpit:-</STRONG><BR /> <P style="overflow: hidden;margin-bottom: 0px"><SPAN style="font-size: 1rem">On click of <STRONG>View Dashboard</STRONG></SPAN> button, <STRONG>SAP Event Mesh - Messaging Administration Cockpit</STRONG> is opened in new tab. Under <STRONG>Overview</STRONG> tab, 3 properties are defined.</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><STRONG>Connections</STRONG>:- Number of active connections which are accessing Event Mesh instance asynchronously.<BR /> <STRONG>Queues</STRONG>:- Number of Message Queues<BR /> <STRONG>Number</STRONG> <STRONG>of</STRONG> <STRONG>Messages</STRONG>:- Number of Messages in queue<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-6.36.06-PM.png" />Click on <STRONG>Queues</STRONG> tab in left side of page. Click on <STRONG>Create</STRONG> button. A popup will appear which will ask for Queue Name<STRONG>. </STRONG>Provide queue name as '<STRONG>demoqueue'</STRONG> and click on <STRONG>Create</STRONG> button.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-6.37.40-PM.png" /></P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-6.41.21-PM.png" /></P><BR /> <P style="overflow: hidden;margin-bottom: 0px">&nbsp;<STRONG>Test SAP Event Mesh Service using Postman Application:-</STRONG></P><BR /> Open <STRONG>Postman</STRONG> application. Create new collection as <STRONG>SAP Event Mesh </STRONG>which will contain HTTP requests related to Event Mesh. There are 4 different types of request.<BR /> <BR /> <STRONG>Token:- </STRONG>POST request which will return access token for message queue. (Success Response Status Code - 200)<BR /> <STRONG>Send Message:- </STRONG>POST request which will push message in queue. (Success Response Status Code - 204)<BR /> <STRONG>Receive Message:- </STRONG>POST request which will fetch message from queue. (Success Response Status Code - 200)<BR /> <STRONG>Acknowledge Message:- </STRONG>POST request which will send acknowledgement to queue that message is consumed successfully from 3rd party system. So queue will delete that message. (Success Response Status Code - 200)<BR /> <BR /> <STRONG>Token:-&nbsp;</STRONG>Create HTTP request as per below parameters. On click of <STRONG>Send </STRONG>button, it will return <STRONG>access_token</STRONG> and <STRONG>token_type</STRONG> in body section.<BR /> <BR /> <STRONG>HTTP Method:-&nbsp;</STRONG>POST<BR /> <STRONG>URL:- </STRONG>&lt;tokenendpoint&gt;<BR /> <STRONG>Params:- </STRONG>grant_type - client_credentials, response_type - token<STRONG><BR /> Authorization:- </STRONG>Basic Authorization, Username - &lt;clientid&gt;, Password - &lt;clientsecret&gt;<STRONG><BR /> Headers:-&nbsp;</STRONG>Content-Type - application/x-www-form-urlencoded<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-7.40.25-PM.png" /><STRONG>Send Message:- </STRONG>Create HTTP request as per below parameters. On click of <STRONG>Send </STRONG>button, It will show status code 204 as we are not getting any response back.<BR /> <BR /> <STRONG>HTTP Method:-&nbsp;</STRONG>POST<BR /> <STRONG>URL:- </STRONG>&lt;uri from httprest protocol section&gt;/messagingrest/v1/queues/&lt;queue name&gt;/messages<BR /> <STRONG>Params:- </STRONG>x-qos - 1, authorization - Bearer &lt;access_token fetched from Token call&gt;<STRONG><BR /> Authorization:- </STRONG>No Authorization<STRONG><BR /> Body:- </STRONG>Data in JSON, Text or in other format which need to send<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-8.03.11-PM.png" />Go back to <STRONG>Overview </STRONG>section of <STRONG>SAP Event Mesh - Messaging Administration Cockpit.&nbsp;</STRONG>User can see 1 Connection and 1 Message via <STRONG>Send Message</STRONG> call (by Postman as shown above). Now click on <STRONG>Queues&nbsp;</STRONG>section which shows that there is 1 message in <STRONG>demoqueue.</STRONG><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-8.04.04-PM.png" /><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-8.03.53-PM.png" /><STRONG>Receive Message:- </STRONG>Create HTTP request as per below parameters. On click of <STRONG>Send </STRONG>button, It will show status code 200 and user can see response data under body section.</P><BR /> <STRONG>HTTP Method:-&nbsp;</STRONG>POST<BR /> <STRONG>URL:- </STRONG>&lt;uri from httprest protocol section&gt;/messagingrest/v1/queues/&lt;queue name&gt;/messages/consumption<BR /> <STRONG>Params:- </STRONG>x-qos - 1, authorization - Bearer &lt;access_token fetched from Token call&gt;<STRONG><BR /> Authorization:- </STRONG>No Authorization<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-8.15.37-PM.png" /><STRONG>Acknowledge Message:- </STRONG>Create HTTP request as per below parameters. On click of <STRONG>Send </STRONG>button, it will show status code 200 and user can see response data under body section.<BR /> <BR /> <STRONG>HTTP Method:-&nbsp;</STRONG>POST<BR /> <STRONG>URL:- </STRONG>&lt;uri from httprest protocol section&gt;/messagingrest/v1/queues/&lt;queue name&gt;/messages/&lt;message id&gt;/acknowledgement<BR /> <STRONG>Params:- </STRONG>x-qos - 1, authorization - Bearer &lt;access_token fetched from Token call&gt;<STRONG><BR /> Authorization:- </STRONG>No Authorization<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-9.17.50-PM.png" /><STRONG>Note:-</STRONG> User can copy message id from response of receive message call (Under Header section).<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-17-at-3.26.33-PM-1.png" />Go to Queues<STRONG>&nbsp;</STRONG>section of <STRONG>SAP Event Mesh - Messaging Administration Cockpit. </STRONG>User can see queue name <STRONG>demoqueue </STRONG>along with 0 number of messages. Message is removed from queue.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-9.29.53-PM-1.png" /><BR /> <BR /> <STRONG>Setup Connection between SAP Event Mesh Service and SAP S/4 HANA (on premise) system through RFC Destination and OAuth Client Profile:-</STRONG><BR /> <BR /> Open SAP On-Premise system with <STRONG>SAP Logon</STRONG>. Open SPRO configuration and press <STRONG>SAP Reference IMG. </STRONG>Here we need to perform below operations.<BR /> <BR /> <STRONG>RFC Destination Setup</STRONG><BR /> <STRONG>OAuth Client Profile Creation</STRONG><BR /> <STRONG>OAuth Client Profile Setup</STRONG><BR /> <BR /> <STRONG>RFC Destination Setup:- </STRONG>Click on SAP Netweaver-&gt;Enterprise Event Enablement-&gt;Administration-&gt;Channel Connection Settings-&gt;Manage RFC Destination entry.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-11.53.24-PM.png" />User can open RFC Destination configuration screen using T-Code SM59 also.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-11.54.41-PM.png" />We will create a connection to external server. Click on <STRONG>Create</STRONG> icon. Provide destination name as '<STRONG>EVENT_MESH_DEMO' </STRONG>and select connection type as '<STRONG>HTTP Connections to External Server' </STRONG>from drop down.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-15-at-11.55.43-PM.png" />Enter an appropriate description for RFC destination. Provide Host name and Port name under <STRONG>Technical Settings</STRONG> tab. Leave other fields as it is.<BR /> Copy URI from HTTPREST protocol section(without 'https://' ) in Service Key on BTP for Host Name. <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-16-at-12.01.43-AM.png" />Click on <STRONG>Logon &amp; Security</STRONG> tab. Under Security Options, Make SSL as Active and select <STRONG>ANONYM SSL Client (Anonymous)</STRONG> as SSL Certificate. Don't make any changes for others. No need to make changes for <STRONG>Special Options&nbsp;</STRONG>tab as well.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-16-at-12.02.00-AM.png" />Save this RFC Destination and Click on <STRONG>Connection Test. </STRONG>You can see Status HTTP Response as 200 and Status Text as OK under<STRONG> Test Result. </STRONG>Go to other tabs like<STRONG> Response Header Fields , Response Body, Response Text </STRONG>and see the result.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-16-at-12.03.52-AM-1.png" /><STRONG>OAuth Client Profile Creation:- </STRONG>Open object navigator using T-Code <STRONG>SE80</STRONG>. Select Local Objects. Right click on <STRONG>Local Object</STRONG>. Under <STRONG>Create</STRONG> icon, User can see various type of development objects. Select on option <STRONG>More</STRONG> which will show option to create <STRONG>OAuth 2.0 Client Profile</STRONG>.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-16-at-12.19.51-AM.png" />Enter Client Profile name as '<STRONG>EVENT_MESH_DEMO_PROFILE'</STRONG> and select Type as '<STRONG>HANA_CLOUD_PLATFORM'</STRONG> from drop down. Click on OK icon. Once new Client Profile is created, Save it.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-16-at-12.23.06-AM.png" /><STRONG>OAuth Client Profile Setup:- </STRONG>Click on SAP Netweaver-&gt;Enterprise Event Enablement-&gt;Administration-&gt;Channel Connection Settings-&gt;Manage OAuth Client Setup entry. (or use T-Code <STRONG>OA2C_CONFIG</STRONG>)<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-16-at-12.24.49-AM.png" />A&nbsp; browser window will open with all the existing OAuth Client Profiles for On-Premise System. Click on <STRONG>Create&nbsp;</STRONG>button in header toolbar.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-16-at-12.25.22-AM.png" />In Popup, Select newly created OAuth 2.0 Client Profile from drop down. Keep Configuration Name same as Profile name. Enter OAuth 2.0 Client ID which was copied from Event Mesh service key in SAP Business Technology Platform.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-16-at-12.28.49-AM.png" />Details of Client Profile will be displayed. In <STRONG>Administration</STRONG> tab, Provide Client Secret, Authorization Endpoint and Token Endpoint which are copied from SAP Event Mesh service key. Other fields are auto populated. Do not make any changes for <STRONG>Scopes</STRONG> and <STRONG>Enhancement Settings</STRONG> tabs. Press <STRONG>Save. </STRONG>User can see updated configurations for Client Profile.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-16-at-12.35.54-AM.png" /><BR /> <BR /> &nbsp;<BR /> <BR /> <STRONG>Demo of data access in On-Premise system:-</STRONG><BR /> <BR /> We will try to access data of message queue through SAP ABAP executable program. Open T-Code <STRONG>SE38.&nbsp;</STRONG>Enter executable report name as '<STRONG>ZRP_READ_EVENT_MESH_DATA' </STRONG>and click on <STRONG>Create&nbsp;</STRONG>button. In popup, Provide meaningful description for report. Click on <STRONG>Save. </STRONG>An empty report will be created.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-16-at-12.42.47-AM.png" />First, Create <STRONG>EVENT_MESH_DEMO&nbsp;</STRONG>destination object and then create <STRONG>EVENT_MESH_DEMO_PROFILE</STRONG> OAuth 2.0 Client Profile object by accessing static methods of class <STRONG>CL_HTTP_CLIENT.&nbsp;</STRONG>Required code is highlighted in below screenshot.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-17-at-6.32.02-PM.png" />Now set token to authorize access of messages from queue<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-17-at-6.38.53-PM.png" />Set <STRONG>x-qos</STRONG> parameter in request header, <STRONG>URI</STRONG> to get message from queue and request method as <STRONG>POST</STRONG>. Now trigger call and receive response from request. This is similar what we have done through Postman application.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-17-at-6.43.16-PM-1.png" />Get data from response. This data will be in same format(JSON, Text etc.) as of the message we have pushed in queue. Once data is retrieved, we can deserialize into deep structure. Then write your logic to parse deep structure data into desired structure as per requirement.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-17-at-6.46.21-PM-1.png" />Once data is successfully retrieved, We will send acknowledgement to queue along with message id which was read earlier. Queue will delete that message.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-17-at-6.48.24-PM.png" />For testing, We will push one more message to <STRONG>demoqueue </STRONG>as shown in below screenshot. User can see newly added message in <STRONG>SAP Event Mesh Cockpit.</STRONG><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-16-at-12.46.57-AM.png" />Execute <STRONG>ZRP_READ_EVENT_MESH_DATA </STRONG>report in debugging mode. We can see message data in <STRONG>ls_payload</STRONG> variable in JSON format as highlighted. In <STRONG>lr_data</STRONG> variable, JSON data is parsed in deep structure via deserializing.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-17-at-7.26.29-PM.png" />By expanding deep structure, we can verify data in debugging mode.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-17-at-7.38.13-PM.png" /><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-17-at-7.39.28-PM.png" />Once data is read, Acknowledgement is sent to queue and queue will delete that message. We can see 0 messages in <STRONG>SAP Event Mesh</STRONG><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/01/Screenshot-2022-01-16-at-7.18.36-PM.png" />You can see ABAP report code <STRONG><A href="https://github.tools.sap/I334119/ReadEventMeshData" target="_blank" rel="noopener nofollow noreferrer">here</A>.</STRONG></P><BR /> <BR /> <H4 id="toc-hId-628086298"><STRONG>Conclusion</STRONG></H4><BR /> We have explained enablement, creation and configuration of SAP Event Mesh service. Along with this, we have learned how to establish connection between SAP Event Mesh service and SAP S/4HANA (on premises) system through demo.<BR /> <BR /> To get more information on SAP Event Mesh, follow the topic page of <A href="https://community.sap.com/topics/event-mesh" target="_blank">SAP Event Mesh</A>. 2022-01-19T16:46:31+01:00 https://community.sap.com/t5/technology-blogs-by-members/import-event-push-of-configuration-text-tables-to-external-database/ba-p/13523708 Import Event Push of Configuration Text Tables to External Database 2022-02-09T22:39:46+01:00 Ryan-Crosby https://community.sap.com/t5/user/viewprofilepage/user-id/13126 <H1 id="toc-hId-830228652">Introduction</H1><BR /> I was recently posed with a problem that needed a new solution for our planned S4 migration in a few weeks. &nbsp;How to get the configuration domain text data to an external database to retain some existing reporting capabilities? &nbsp;I'm betting that a lot of folks work in heterogenous landscapes and sometimes it requires getting creative with how to tackle a problem. &nbsp;I have seen a couple of approaches in the past and have to admit that I'm not a fan of either, but I'll let you decide for yourself which one is least preferred. &nbsp;First example - two synchronous ABAP Proxies of megalith proportions statically defined to return data on several dozen configuration domains based on daily or weekly frequency. &nbsp;The second - several recurring job instances throughout the day (<EM>four or five maybe</EM>) that extract the data whenever change pointers are detected on dependent business objects, and saved as files on the application server, which requires some other process to fetch the data and load it.&nbsp; Is a many times daily, daily, or weekly cadence appropriate given the relatively infrequency that configuration tables are updated in a productive environment?<BR /> <H1 id="toc-hId-633715147">Proposal</H1><BR /> What if there were an event that could push the data for a pit stop into Integration Suite for some transformation before reaching its final destination in the external database? &nbsp;I spent a few hours pondering the question and came up with the following: Implement BADI CTS_IMPORT_FEEDBACK along with BRF+ to evaluate customizing requests and push table names to Integration Suite. &nbsp;Start with an iterating splitter, and sprinkle a little graphical mapping, content enricher via OData, and XSL transform and arrive at XML that can be processed by the JDBC adapter to initiate stored procedures for UPSERT. &nbsp;What follows is the culmination of a day and a half of build, learning, and experimentation with a couple of gotchas along the way.<BR /> <H1 id="toc-hId-437201642">ABAP</H1><BR /> The original intent was to execute the entirety of ABAP within this BADI method, but after I had completed the full service layer in Integration Suite and worked backward into this method, I discovered that it executes in client 000, and received a ST22 dump when the BRF+ application could not execute. &nbsp;The BRF+ code was pushed into the RFC function module. &nbsp;Consequently, after working in SAP software for 14 years and having never logged in to client 000, I have for the first time (<EM>SM59 destination</EM>), and doubtful I ever would again. &nbsp;You may also wonder why I wouldn't simply read keys and use a combination of RTTS and web services to push the data to Integration Suite. &nbsp;Beyond avoiding the megalith mentioned above, dealing with situations where some columns are ignored for certain tables, and determining appropriate structure, it certainly wouldn't be blog worthy and you wouldn't be reading this! &nbsp;After following the remaining steps I think it will be clear why I decided to go with the chosen route.<BR /> <PRE class="language-abap"><CODE>METHOD if_ex_cts_import_feedback~feedback_after_import.<BR /> <BR /> DATA: corr TYPE trwbo_request,<BR /> tables TYPE tt_tabnames.<BR /> <BR /> * Read object keys for import<BR /> CLEAR: tables.<BR /> LOOP AT requests INTO DATA(request).<BR /> CLEAR corr.<BR /> CALL FUNCTION 'TR_READ_REQUEST'<BR /> EXPORTING<BR /> iv_read_objs_keys = 'X'<BR /> iv_trkorr = request-trkorr<BR /> CHANGING<BR /> cs_request = corr<BR /> EXCEPTIONS<BR /> error_occured = 1<BR /> no_authorization = 2<BR /> OTHERS = 3.<BR /> <BR /> IF sy-subrc = 0.<BR /> * Record any tables for evaluation in BRF+<BR /> LOOP AT corr-keys INTO DATA(key)<BR /> WHERE object = 'TABU'.<BR /> APPEND key-objname TO tables.<BR /> ENDLOOP.<BR /> ELSE.<BR /> * Should never happen based on data requested in FM<BR /> ENDIF.<BR /> ENDLOOP.<BR /> <BR /> * Sort and remove duplicates and pass to RFC for<BR /> * communication<BR /> SORT tables.<BR /> DELETE ADJACENT DUPLICATES FROM tables.<BR /> CALL FUNCTION 'ZCA_WS_CONFIG_UPDATE_DISPATCH'<BR /> DESTINATION 'CFGUPDDISP'<BR /> EXPORTING<BR /> table = tables.<BR /> <BR /> ENDMETHOD.</CODE></PRE><BR /> Originally, this RFC was only intended to be a shell for my enterprise service consumer proxy generation (<EM>we do not have an ESR</EM>), but after experiencing the client 000 problem it became a suitable surrogate to execute the BRF+ application in the appropriate client, as well as the ABAP proxy.<BR /> <PRE class="language-abap"><CODE> FUNCTION zca_ws_config_update_dispatch.<BR /> *"----------------------------------------------------------------------<BR /> *"*"Local Interface:<BR /> *" IMPORTING<BR /> *" VALUE(TABLE) TYPE TT_TABNAMES<BR /> *"----------------------------------------------------------------------<BR /> <BR /> DATA:timestamp TYPE timestamp,<BR /> t_name_value TYPE abap_parmbind_tab,<BR /> name_value TYPE abap_parmbind,<BR /> r_data TYPE REF TO data,<BR /> input TYPE zzca_ws_config_update_dispatch,<BR /> proxy TYPE REF TO zco_zws_config_update_dispatch.<BR /> <BR /> CONSTANTS: function_id TYPE if_fdt_types=&gt;id VALUE '005056977E091EECA1F05A7D5FE1B25F'.<BR /> <BR /> * Set timestamp for processing and move input data into reference<BR /> GET TIME STAMP FIELD timestamp.<BR /> name_value-name = 'TT_TABNAMES'.<BR /> GET REFERENCE OF table INTO r_data.<BR /> cl_fdt_function_process=&gt;move_data_to_data_object( EXPORTING ir_data = r_data<BR /> iv_function_id = function_id<BR /> iv_data_object = '005056977E091EECA1F05DC93384D25F' "TT_TABNAMES<BR /> iv_timestamp = timestamp<BR /> iv_trace_generation = abap_false<BR /> iv_has_ddic_binding = abap_true<BR /> IMPORTING er_data = name_value-value ).<BR /> INSERT name_value INTO TABLE t_name_value.<BR /> CLEAR name_value.<BR /> <BR /> TRY.<BR /> * Execute BRF+ function<BR /> cl_fdt_function_process=&gt;process( EXPORTING iv_function_id = function_id<BR /> iv_timestamp = timestamp<BR /> IMPORTING ea_result = input-table-item<BR /> CHANGING ct_name_value = t_name_value ).<BR /> <BR /> * Only execute proxy if any tables of interest are found<BR /> IF input-table-item[] IS NOT INITIAL.<BR /> CREATE OBJECT proxy.<BR /> CALL METHOD proxy-&gt;zca_ws_config_update_dispatch<BR /> EXPORTING<BR /> input = input.<BR /> <BR /> COMMIT WORK.<BR /> ENDIF.<BR /> <BR /> CATCH cx_fdt.<BR /> * Do what on error?<BR /> CATCH cx_ai_system_fault.<BR /> * Do what on error?<BR /> ENDTRY.<BR /> <BR /> ENDFUNCTION.</CODE></PRE><BR /> <H1 id="toc-hId-240688137">BRF+</H1><BR /> I find BRF+ to be an often underutilized gem in the system. &nbsp; If I have a simple question for the system to answer, pass the necessary input and let it determine the outcome. &nbsp;The true beauty is that I can add or remove a table for this scenario without writing a single line of ABAP!!<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/02/Screen-Shot-2022-02-08-at-08.19.11.png" /></P><BR /> <BR /> <H1 id="toc-hId-44174632">Integration Flow</H1><BR /> The first two steps of the flow are setup steps to determine the backend OData host and split the incoming message by each table. &nbsp;The last three steps will be presented in more detail below.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/02/Screen-Shot-2022-02-08-at-10.02.13.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Full E2E Integration Process</P><BR /> <BR /> <H1 id="toc-hId--152338873">Graphical Mapping</H1><BR /> This mapping serves the purpose of mapping a backend table name into four corresponding bits of data... stored procedure, OData service name, resource, and query using a combination of the fixValues function and a couple of simple Groovy scripts. &nbsp;Folks could be wondering why not use value mapping, but I feel like that is a lot of overkill to maintain several input fields instead of simple 1:1 mappings with fixValues. &nbsp;Also, note the use of the query parameter is used because for one table we don't want the full field list. &nbsp;If we use $select query options for one table in the OData adapter we must maintain it for all (<I>Tried the empty string and it did not work</I>). &nbsp;This leaves me with a choice dilemma:<BR /> <BR /> <STRONG>Option 1 -&nbsp;</STRONG>Add a query parameter, which is more stuff to maintain in the graphical mapping<BR /> <BR /> <STRONG>Option 2 -&nbsp;</STRONG>Do not add query parameter and handle stripping of extra fields in XSL transform<BR /> <BR /> Since I'd rather not select fields and transport extra data over the network that is of no consequence, I went with the first option.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/02/Screen-Shot-2022-02-08-at-08.22.11.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">Graphical mapping for OData/Stored procedure determination</P><BR /> The setHeader function should be self explanatory, but the joinContexts function is to establish a queue like some of the older PI/PO functions. &nbsp;I could not find an equivalent in Integration Suite, so I constructed my own (<EM>Feel free to share if there is some out of the box option that I could not find</EM>).<BR /> <PRE class="language-java"><CODE>// Insert message headers<BR /> def void setHeader(String[] keys, String[] values, Output output, MappingContext context){<BR /> def i = 0;<BR /> while(i &lt; keys.size()) {<BR /> context.setHeader(keys[i], values[i]);<BR /> i++;<BR /> }<BR /> }<BR /> <BR /> // Create context queue to match keys with values<BR /> def void joinContexts(String[] input1, String[] input2, String[] input3, Output output, MappingContext context){<BR /> output.addValue(input1[0]);<BR /> output.addValue(input2[0]);<BR /> output.addValue(input3[0]);<BR /> }</CODE></PRE><BR /> <H1 id="toc-hId--348852378">Content Enricher via OData</H1><BR /> The first image includes basic host and service metadata that is handled in the first step, and the graphical mapping step. &nbsp;I was unsure if externalized parameters and headers would be concatenated like two headers, so I went with this option. &nbsp;If externalized parameters do work in this way, then I could eliminate the first step in the flow. &nbsp;The second image shows the processing tab with the other metadata required for the OData service call. &nbsp;You may be wondering at this point... what about V2 vs. V4? &nbsp;For the 10 tables I need to push, I was able to identify 2 services that are both V2. &nbsp;If I have to cross that bridge in the future, I can manage with the addition of a version metadata field in the graphical mapping and an appropriate routing step.<BR /> <H1 id="toc-hId--545365883"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/02/Screen-Shot-2022-02-08-at-10.23.12.png" /></H1><BR /> <P class="image_caption" style="font-style: italic;font-family: SAPRegular, 'Helvetica Neue', Arial, sans-serif;text-align: center">OData Connection Information</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/02/Screen-Shot-2022-02-08-at-10.28.59.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">OData Processing Information</P><BR /> The following XML is the result after the content enricher via OData using the combine algorithm. &nbsp;The nice feature/outcome being that I did not have to statically define any table structures or field types anywhere in the solution.<BR /> <PRE class="language-markup"><CODE>&lt;?xml version='1.0' encoding='UTF-8'?&gt;<BR /> &lt;multimap:Messages xmlns:multimap="http://sap.com/xi/XI/SplitAndMerge"&gt;<BR /> &lt;multimap:Message1&gt;<BR /> &lt;Root&gt;<BR /> &lt;StoredProcedure&gt;sp_TVV1T&lt;/StoredProcedure&gt;<BR /> &lt;/Root&gt;<BR /> &lt;/multimap:Message1&gt;<BR /> &lt;multimap:Message2&gt;<BR /> &lt;AdditionalCustomerGroup1&gt; <BR /> &lt;AdditionalCustomerGroup1&gt; <BR /> &lt;AdditionalCustomerGroup1_ID&gt;T01&lt;/AdditionalCustomerGroup1_ID&gt;<BR /> &lt;AdditionalCustomerGroup1Text&gt;Tier 1&lt;/AdditionalCustomerGroup1Text&gt; <BR /> &lt;/AdditionalCustomerGroup1&gt; <BR /> &lt;AdditionalCustomerGroup1&gt; <BR /> &lt;AdditionalCustomerGroup1_ID&gt;T02&lt;/AdditionalCustomerGroup1_ID&gt;<BR /> &lt;AdditionalCustomerGroup1Text&gt;Tier 2&lt;/AdditionalCustomerGroup1Text&gt; <BR /> &lt;/AdditionalCustomerGroup1&gt; <BR /> &lt;AdditionalCustomerGroup1&gt; <BR /> &lt;AdditionalCustomerGroup1_ID&gt;T03&lt;/AdditionalCustomerGroup1_ID&gt; <BR /> &lt;AdditionalCustomerGroup1Text&gt;Tier 3&lt;/AdditionalCustomerGroup1Text&gt; <BR /> &lt;/AdditionalCustomerGroup1&gt; <BR /> &lt;AdditionalCustomerGroup1&gt; <BR /> &lt;AdditionalCustomerGroup1_ID&gt;T04&lt;/AdditionalCustomerGroup1_ID&gt; <BR /> &lt;AdditionalCustomerGroup1Text&gt;Tier 4&lt;/AdditionalCustomerGroup1Text&gt; <BR /> &lt;/AdditionalCustomerGroup1&gt; <BR /> &lt;AdditionalCustomerGroup1&gt; <BR /> &lt;AdditionalCustomerGroup1_ID&gt;T05&lt;/AdditionalCustomerGroup1_ID&gt;<BR /> &lt;AdditionalCustomerGroup1Text&gt;Tier 5&lt;/AdditionalCustomerGroup1Text&gt;<BR /> &lt;/AdditionalCustomerGroup1&gt; <BR /> &lt;AdditionalCustomerGroup1&gt;<BR /> &lt;AdditionalCustomerGroup1_ID/&gt;<BR /> &lt;AdditionalCustomerGroup1Text/&gt; <BR /> &lt;/AdditionalCustomerGroup1&gt; <BR /> &lt;/AdditionalCustomerGroup1&gt;<BR /> &lt;/multimap:Message2&gt;<BR /> &lt;/multimap:Messages&gt;</CODE></PRE><BR /> <H1 id="toc-hId--741879388">XSL Transform</H1><BR /> For the sake of brevity, I have included a truncated XSL transform that only includes 3 tables despite my requirement being 10 tables. &nbsp;If you happen to be a savvy XSL veteran, and find my work to be rudimentary, keep in mind that this is my first XSL transform after spending 30 minutes reading and learning on W3Schools. &nbsp;I did implement the XSL transform in such a way that empty string key records would be removed from the stream.<BR /> <PRE class="language-markup"><CODE>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<BR /> <BR /> &lt;xsl:stylesheet version="1.0"<BR /> xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:multimap="http://sap.com/xi/XI/SplitAndMerge"&gt;<BR /> <BR /> &lt;xsl:template match="/"&gt;<BR /> &lt;root&gt;<BR /> &lt;StatementName&gt;<BR /> &lt;storedProcedureName action="EXECUTE"&gt;<BR /> &lt;table&gt;&lt;xsl:value-of select="multimap:Messages/multimap:Message1/Root/StoredProcedure"/&gt;&lt;/table&gt;<BR /> &lt;ProcedureParameter type="CLOB"&gt;<BR /> &lt;xsl:text disable-output-escaping="yes"&gt;&amp;lt;![CDATA[&lt;/xsl:text&gt;<BR /> <BR /> &lt;!-- TVM4T Procedure --&gt;<BR /> &lt;xsl:for-each select="multimap:Messages/multimap:Message2/AdditionalMaterialGroup4"&gt;<BR /> &lt;List&gt;<BR /> &lt;xsl:for-each select="AdditionalMaterialGroup4[AdditionalMaterialGroup4_ID!='']"&gt;<BR /> &lt;Item&gt;<BR /> &lt;MaterialGroup4&gt;&lt;xsl:value-of select="AdditionalMaterialGroup4_ID"/&gt;&lt;/MaterialGroup4&gt;<BR /> &lt;MaterialGroup4Text&gt;&lt;xsl:value-of select="AdditionalMaterialGroup4Text"/&gt;&lt;/MaterialGroup4Text&gt;<BR /> &lt;/Item&gt;<BR /> &lt;/xsl:for-each&gt;<BR /> &lt;/List&gt;<BR /> &lt;/xsl:for-each&gt;<BR /> <BR /> &lt;!-- TVM5T Procedure --&gt;<BR /> &lt;xsl:for-each select="multimap:Messages/multimap:Message2/AdditionalMaterialGroup5"&gt;<BR /> &lt;List&gt;<BR /> &lt;xsl:for-each select="AdditionalMaterialGroup5[AdditionalMaterialGroup5_ID!='']"&gt;<BR /> &lt;Item&gt;<BR /> &lt;MaterialGroup5&gt;&lt;xsl:value-of select="AdditionalMaterialGroup5_ID"/&gt;&lt;/MaterialGroup5&gt;<BR /> &lt;MaterialGroup5Text&gt;&lt;xsl:value-of select="AdditionalMaterialGroup5Text"/&gt;&lt;/MaterialGroup5Text&gt;<BR /> &lt;/Item&gt;<BR /> &lt;/xsl:for-each&gt;<BR /> &lt;/List&gt;<BR /> &lt;/xsl:for-each&gt;<BR /> <BR /> &lt;!-- TVV1T Procedure --&gt;<BR /> &lt;xsl:for-each select="multimap:Messages/multimap:Message2/AdditionalCustomerGroup1"&gt;<BR /> &lt;List&gt;<BR /> &lt;xsl:for-each select="AdditionalCustomerGroup1[AdditionalCustomerGroup1_ID!='']"&gt;<BR /> &lt;Item&gt;<BR /> &lt;CustomerGroup1&gt;&lt;xsl:value-of select="AdditionalCustomerGroup1_ID"/&gt;&lt;/CustomerGroup1&gt;<BR /> &lt;CustomerGroup1Text&gt;&lt;xsl:value-of select="AdditionalCustomerGroup1Text"/&gt;&lt;/CustomerGroup1Text&gt;<BR /> &lt;/Item&gt;<BR /> &lt;/xsl:for-each&gt;<BR /> &lt;/List&gt;<BR /> &lt;/xsl:for-each&gt;<BR /> <BR /> &lt;xsl:text disable-output-escaping="yes"&gt;]]&amp;gt;&lt;/xsl:text&gt;<BR /> &lt;/ProcedureParameter&gt;<BR /> &lt;/storedProcedureName&gt;<BR /> &lt;/StatementName&gt;<BR /> &lt;/root&gt;<BR /> &lt;/xsl:template&gt;<BR /> <BR /> &lt;/xsl:stylesheet&gt;</CODE></PRE><BR /> The resulting XML is JDBC adapter ready<BR /> <PRE class="language-markup"><CODE>&lt;root xmlns:multimap="http://sap.com/xi/XI/SplitAndMerge"&gt;<BR /> &lt;StatementName&gt;<BR /> &lt;storedProcedureName action="EXECUTE"&gt;<BR /> &lt;table&gt;sp_TVV1T&lt;/table&gt;<BR /> &lt;ProcedureParameter type="CLOB"&gt;<BR /> &lt;![CDATA[<BR /> &lt;List&gt;<BR /> &lt;Item&gt;&lt;CustomerGroup1&gt;T01&lt;/CustomerGroup1&gt;&lt;CustomerGroup1Text&gt;Tier 1&lt;/CustomerGroup1Text&gt;&lt;/Item&gt;<BR /> &lt;Item&gt;&lt;CustomerGroup1&gt;T02&lt;/CustomerGroup1&gt;&lt;CustomerGroup1Text&gt;Tier 2&lt;/CustomerGroup1Text&gt;&lt;/Item&gt;<BR /> &lt;Item&gt;&lt;CustomerGroup1&gt;T03&lt;/CustomerGroup1&gt;&lt;CustomerGroup1Text&gt;Tier 3&lt;/CustomerGroup1Text&gt;&lt;/Item&gt;<BR /> &lt;Item&gt;&lt;CustomerGroup1&gt;T04&lt;/CustomerGroup1&gt;&lt;CustomerGroup1Text&gt;Tier 4&lt;/CustomerGroup1Text&gt;&lt;/Item&gt;<BR /> &lt;Item&gt;&lt;CustomerGroup1&gt;T05&lt;/CustomerGroup1&gt;&lt;CustomerGroup1Text&gt;Tier 5&lt;/CustomerGroup1Text&gt;&lt;/Item&gt;<BR /> &lt;/List&gt;<BR /> ]]&gt;<BR /> &lt;/ProcedureParameter&gt;<BR /> &lt;/storedProcedureName&gt;<BR /> &lt;/StatementName&gt;<BR /> &lt;/root&gt;</CODE></PRE><BR /> <H1 id="toc-hId--938392893">JDBC</H1><BR /> <STRONG>Disclaimer:</STRONG> This part has not actually been tested, but instead the above XML was dumped to an FTP site for extraction during unit testing.<BR /> <BR /> Once the DB admins are able to create the necessary stored procedures I will include an editorial update. &nbsp;In the past, I have used the JDBC adapter in PI/PO where we can do bulk inserts, but I did stumble upon some blog/answer posts, and an OSS note indicating that bulk inserts are not supported in Integration Suite unless using a splitter in batch mode. &nbsp;I referred to the following blog on the topic of using stored procedures, which I had used in the past in PI/PO -&nbsp;<A href="https://blogs.sap.com/2021/09/30/sap-cloud-integration-cpi-hci-jdbc-adapter-part-3-update-the-db-using-jdbc-adapter-via-a-stored-procedure-parameter-as-xml-type/" target="_blank" rel="noopener noreferrer">Stored procedure as XML Type</A>&nbsp; I opted not to split an already split message, along with the fact that this approach fares far better from a performance perspective.<BR /> <H1 id="toc-hId--365166315">Conclusion</H1><BR /> After reaching a point where I can successfully unit test the full solution outside of of the JDBC handling, I'm pleased with the outcome. &nbsp;For future's sake, if I need to add a new table in the future the process is quite simple:<BR /> <OL><BR /> <LI>Add table to BRF+ expression</LI><BR /> <LI>Identify/build an OData service - <STRONG>Note:</STRONG> if you have spent inordinate amounts of time working backward from tables to a usable OData service, then you are not alone, and I would rather reuse than build. &nbsp;I don't need draft capabilities for this type of thing and I'm still presented with choosing from multiple options... whatever happened to software reusability, but that's a topic for another day</LI><BR /> <LI>Add four bits of metadata (<EM>maybe five if versioning enters the picture</EM>) for OData and a stored procedure into the graphical mapping step</LI><BR /> <LI>Add a new block to the XSL transform</LI><BR /> <LI>Get a DB Admin to create the required stored procedure</LI><BR /> </OL><BR /> &nbsp;<BR /> <BR /> Hope folks can get something useful out of this... enjoy! 2022-02-09T22:39:46+01:00 https://community.sap.com/t5/technology-blogs-by-members/sapjsf-user-gets-frequently-locked/ba-p/13525697 SAPJSF user gets frequently locked 2022-02-10T11:15:36+01:00 Kumar_Sonal https://community.sap.com/t5/user/viewprofilepage/user-id/144775 <P style="text-align: left">In this blog we are going to discuss how to resolve the SAPJSF user getting locked issue due to incorrect logon attempts.</P><BR /> <P style="text-align: left">Before diving into this, i want to give a little bit of background to issue. I was facing this issue since May 2021. After checking and applying various SNOTE, the issue was not resolved. I am using Dual Stack ( ABAP + JAVA ) running on NetWeaver 7.4. I raised SAP OSS but the support was unable to resolve this issue and finally suggested the upgrade to NetWeaver 7.5. I was able to resolve this without the upgrade.</P><BR /> <P style="text-align: left"><STRONG>Cause :</STRONG></P><BR /> <P style="text-align: left">This issue occurs when SAPJSF password has been updated ( by a user or by system upgrade/implementation/change etc. ) .</P><BR /> <P style="text-align: left">In a dual stack system, this leads to failed attempts by SAPJSF user as the same SAPJSF password has not been updated at following places :</P><BR /> <BR /> <OL style="text-align: left"><BR /> <LI>ABAP SAP GUI</LI><BR /> <LI>OS application server ( Configtool )</LI><BR /> <LI>SAP NetWeaver portal ( JCO and RFC destinations )</LI><BR /> </OL><BR /> <P style="text-align: left"><STRONG>Resolution :</STRONG></P><BR /> <P style="text-align: left">To resolve this issue we have to update the same SAPJSF password at all the three locations mentioned above.</P><BR /> <BR /> <OL style="text-align: left"><BR /> <LI><EM>Go to SU01</EM> – Change and Update the SAPJSF password and save the changes.</LI><BR /> <LI>Login to the OS level of the java application server and follow the steps below:</LI><BR /> </OL><BR /> <UL style="text-align: left"><BR /> <LI>Login to your J2EE engine operating system. Open the <EM>Config Tool</EM>. Choose <EM>Global server configuration &gt; services &gt; com.sap.security.core.ume.service.</EM> Change the password on <EM>ume.r3.connection.master.passwd</EM>.</LI><BR /> <LI>The config tool located under /usr/sap/&lt;SAP SID&gt;/&lt;Instance Dir.&gt;/j2ee/configtool/configtool.bat or .sh *</LI><BR /> </UL><BR /> <P style="text-align: left">&nbsp; &nbsp; &nbsp; &nbsp;3. Login to NetWeaver portal : Configuration &gt; connectivity &gt; destination. find : RFC destination UME Backend connection &gt; logo data &gt; edit &gt; update SAPJSF password. (check first if user is SAPJSF).<EM>Then Go to SU01 &gt; Unlock the SAPJSF user manually. Restart the Java instance from SAP MMC at OS level.</EM></P><BR /> <BR /> <OL style="text-align: left" start="4"><BR /> <LI style="text-align: left">Login to NetWeaver portal :<EM>Configuration &gt; connectivity &gt; JCO connector</EM>. You will find the list of running TCP/IP connection. Check logon data of each connection and if the USER is SAPJSF and then update the password. <EM>Then Go to SU01 &gt; Unlock the SAPJSF user manually. Restart the Java instance from SAP MMC at OS level.</EM></LI><BR /> </OL><BR /> <P style="text-align: left">After following the above steps, I have resolved this issue.</P><BR /> <P style="text-align: left"><STRONG>Conclusion :</STRONG></P><BR /> <P style="text-align: left">In a dual stack system , Communication user SPAJSF is used for establishing the connection between ABAP and JAVA. In a single stack JAVA only system, this user is used for internal communication.</P><BR /> <P style="text-align: left">The same password should be maintained at the destination and user sheet, otherwise this will lead to SAPJSF user getting locked frequently.</P><BR /> <P style="text-align: left">I hope this blog is helpful to you. Please feel free to drop any questions and clarification if any.</P> 2022-02-10T11:15:36+01:00 https://community.sap.com/t5/technology-blogs-by-members/interfacing-web-apps-with-sap/ba-p/13527393 Interfacing web apps with SAP 2022-04-05T19:46:09+02:00 evora-it https://community.sap.com/t5/user/viewprofilepage/user-id/660007 Businesses are unique, and so are their challenges. Evora designs, builds, and implements custom-tailored solutions based on modern technologies and best practices. As a long-time SAP partner, we have extensive experience in developing custom apps and connecting them to SAP backend systems. I spoke to my colleague&nbsp;<SPAN class="mention-scrubbed">fredericpollmann</SPAN> about his project experience so I could share the learnings with the SAP community.<BR /> <H2 id="toc-hId-959426965">Leveraging SAP Gateway</H2><BR /> <SPAN lang="EN-US">SAP Gateway is part of SAP NetWeaver, which allows to connect devices, applications, and platforms to SAP systems. For the integration, the Open Data Protocol (OData) is used, so any programming language or model can be used to connect SAP systems with non-SAP applications.</SPAN><BR /> <BR /> Using a familiar RFC interface, developers can easily create OData. As a JSON dialect, it offers easy integration with all kinds of frontend technologies and frameworks that are prepared to consume data out of REST services, even if you do not want to use or implement the entire OData functionality. While the main job of the gateway is to pass data on, it can also be used to fetch, refine, and transform it based on your requirements along the way.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/02/WebDevArchitecture.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Leveraging SAP Gateway</P><BR /> <BR /> <H2 id="toc-hId-762913460">Our Technology Stack for hybrid web apps</H2><BR /> In one customer case for a field service app at a technology company, we built a hybrid web app using Angular, Bootstrap, and Apache Cordova. The core of this application runs on iPads and Windows 10 convertible devices and is accessible as a web page - all built from the same code base.<BR /> <BR /> <STRONG>Flexible Architecture</STRONG><BR /> <BR /> The application logic is built with Angular and is heavily dependent on rxjs and the reactive programming paradigm. This allows us to easily update the application whenever data changes.<BR /> <BR /> <STRONG>Beautiful User Interfaces</STRONG><BR /> <BR /> Using Bootstrap as the UI framework allows us to quickly achieve results and build applications that the user intuitively understands. Applying a theme allows us to easily match the app to the customers corporate design colors and style guide.<BR /> <BR /> <STRONG>One Code Base</STRONG><BR /> <BR /> Everything is bundled together in a Cordova app which gives us cross-platform capabilities. And thanks to using a mono-repository approach, the source code for the core libraries and different app shells lives in the same code repository and ensures that we don’t have problems with broken dependencies.<BR /> <BR /> <STRONG>Automatic Synchronization</STRONG><BR /> <BR /> By integrating the Apple push notifications service into the RFCs, we can trigger a sync between mobile clients and backend whenever required without manual refresh.<BR /> <BR /> What technology you use? What piece of knowledge regarding web app development you would like to share? Looking forward to the discussion, please provide feedback in the comments section here.<BR /> <BR /> <EM>Disclaimer: all information and images are created by Evora IT Solutions.Note that this post first appeared at <A href="https://www.evorait.com/2022/02/11/interfacing-web-apps-with-sap" target="test_blank" rel="nofollow noopener noreferrer">https://www.evorait.com/2022/02/11/interfacing-web-apps-with-sap</A>.</EM> 2022-04-05T19:46:09+02:00 https://community.sap.com/t5/enterprise-resource-planning-blogs-by-members/shipment-data-transfer-from-ecc-to-tm-without-middleware/ba-p/13543200 Shipment Data Transfer from ECC to TM Without Middleware 2022-06-10T22:17:27+02:00 poulamidas https://community.sap.com/t5/user/viewprofilepage/user-id/801487 There are multiple ways to send data from one SAP system to another for several scenarios. IDocs and webservices can fulfil most of your integration requirements. However, there maybe times when your project requires you to achieve something that is not standard SAP behaviour. And when SAP does not provide such functionalities, you must figure out a workaround.<BR /> <BR /> One of those scenarios is Shipment Transfer from ECC system to TM system without a middleware.<BR /> SAP does not allow point-to-point connection for data transfer from Shipment in ECC to Freight Order in TM system. It mandates the use of PI system as a middleware. This means that once you have triggered Shipment creation from a Freight Order in TM, you do not have the confirmation from&nbsp; ERP system if PI system is not involved. Furthermore, any change of Shipment Status is also not sent back to TM system. Hence, the Freight Order Status remains unchanged.<BR /> <BR /> In this blogpost, I have shared the solution to send shipment data from ECC system to TM system. The data includes both confirmation details as well as status change details. We will be building an RFC that will be called by the ECC system and will update the corresponding Freight Order in TM system. If required, similar solution can be used for numerous Freight Order fields with the right bit of BOPF coding.<BR /> <BR /> Attached below are the screenshots of the Freight Order fields I will update based on Shipment Data<BR /> in ECC.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/blog1-1.png" height="222" width="432" /></P><BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/blog2.png" height="214" width="202" /><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/blog3.png" /></P><BR /> &nbsp;<BR /> <BR /> <STRONG>Prerequisite:</STRONG><BR /> <BR /> • Basic understanding of BO structure<BR /> • Knowledge of BOPF coding<BR /> • Understanding of BO node actions<BR /> <BR /> <STRONG>The fields to be updated are:</STRONG><BR /> <BR /> 1. Carrier<BR /> 2. Transmission-to-ERP status<BR /> 3. Last ERP Confirmation On/At<BR /> 4. Lifecyle Status<BR /> 5. Execution Status<BR /> 6. Logistical Execution Status<BR /> <BR /> And this is the mapping between the ECC shipment fields and the corresponding status in FO in TM. When the Shipment Status fields are checked (‘X’), the corresponding status code should be updated in FO in TM system.<BR /> <TABLE style="height: 340px" width="496"><BR /> <TBODY><BR /> <TR style="height: 56px"><BR /> <TD style="width: 105.323px;height: 56px">Shipment Status Field (X)</TD><BR /> <TD style="width: 121.552px;height: 56px">Execution Status (SAP TM)</TD><BR /> <TD style="width: 111.094px;height: 56px">Lifecycle Status (SAP TM)</TD><BR /> <TD style="width: 130.031px;height: 56px">Logistical Execution Status (TM system)</TD><BR /> </TR><BR /> <TR style="height: 56px"><BR /> <TD style="width: 105.323px;height: 56px">VTTK-STLBG</TD><BR /> <TD style="width: 121.552px;height: 56px">Loading In Process (09)</TD><BR /> <TD style="width: 111.094px;height: 56px">In Process (02)</TD><BR /> <TD style="width: 130.031px;height: 56px"></TD><BR /> </TR><BR /> <TR style="height: 56px"><BR /> <TD style="width: 105.323px;height: 56px">VTTK-STLAD</TD><BR /> <TD style="width: 121.552px;height: 56px">Ready for Transportation Execution (07)</TD><BR /> <TD style="width: 111.094px;height: 56px">In Process (02)</TD><BR /> <TD style="width: 130.031px;height: 56px">Loaded (18)</TD><BR /> </TR><BR /> <TR style="height: 42px"><BR /> <TD style="width: 105.323px;height: 42px">VTTK-STTBG</TD><BR /> <TD style="width: 121.552px;height: 42px">In Execution (03)</TD><BR /> <TD style="width: 111.094px;height: 42px">In Process (02)</TD><BR /> <TD style="width: 130.031px;height: 42px"></TD><BR /> </TR><BR /> <TR style="height: 42px"><BR /> <TD style="width: 105.323px;height: 42px">VTTK-STTEN</TD><BR /> <TD style="width: 121.552px;height: 42px">Executed (04)</TD><BR /> <TD style="width: 111.094px;height: 42px">In Process (02)</TD><BR /> <TD style="width: 130.031px;height: 42px"></TD><BR /> </TR><BR /> <TR style="height: 24px"><BR /> <TD style="width: 105.323px;height: 24px">VTTK-STABF</TD><BR /> <TD style="width: 121.552px;height: 24px">Executed (04)</TD><BR /> <TD style="width: 111.094px;height: 24px">Completed (05)</TD><BR /> <TD style="width: 130.031px;height: 24px"></TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> &nbsp;<BR /> <H3 id="toc-hId-1090236319"><STRONG>Step 1: Build RFC Function Module in TM system</STRONG></H3><BR /> First, we will build the <STRONG>RFC (Remote Function Call)</STRONG> which will be called from ECC. The RFC will be developed in TM system and will be called when the Shipment is created, updated, or deleted. Identify the nodes in which the above fields are present.<BR /> <BR /> Of the above TM fields, all, except the Logistical Execution Status field, are present in the <STRONG>Root Node</STRONG>. Therefore, the actions to update the fields will be present under the Root Node. The Actions are:<BR /> <OL><BR /> <LI><STRONG>ASSIGN_TSP</STRONG> (To Update carrier)</LI><BR /> <LI><STRONG>SET_EXM_STATUS_EXECUTED</STRONG> (Set&nbsp;Execution&nbsp;status&nbsp;to&nbsp;Executed)</LI><BR /> <LI><STRONG>SET_LC_COMPLETE</STRONG> (Set&nbsp;lifecycle&nbsp;status&nbsp;to&nbsp;Processed)</LI><BR /> <LI><STRONG>SET_LC_IN_PROCESS</STRONG> (Set&nbsp;lifecycle&nbsp;status&nbsp;in&nbsp;Process)</LI><BR /> <LI><STRONG>SET_EXM_STATUS_READY_FOR_EXEC</STRONG> (Set&nbsp;Execution&nbsp;Status&nbsp;to&nbsp;Ready&nbsp;for&nbsp;Execution)</LI><BR /> <LI><STRONG>SET_EXM_STATUS_IN_LOADING</STRONG> (Set&nbsp;Execution&nbsp;Status&nbsp;to&nbsp;in&nbsp;Loading)</LI><BR /> <LI><STRONG>SET_EXM_STATUS_IN_EXECUTION</STRONG> (Set&nbsp;Execution&nbsp;Status&nbsp;to&nbsp;In&nbsp;Execution)</LI><BR /> </OL><BR /> The Logistical Execution Status field is present under <STRONG>STOP Node </STRONG>and the action to change its status to ‘<STRONG>Loaded</STRONG>’ is <STRONG>SET_HANDLING_EXECUTION</STRONG>.<BR /> <BR /> The fields <STRONG>Transmission-to-ERP status</STRONG> and <STRONG>Last ERP Confirmation On/At</STRONG> are updated by <STRONG>MODIFY </STRONG>method of Interface <STRONG>/BOBF/IF_TRA_SERVICE_MANAGER.</STRONG><BR /> <BR /> The above <STRONG>Actions </STRONG>are executed using the method <STRONG>DO_ACTION </STRONG>of interface <STRONG>/BOBF/IF_TRA_SERVICE_MANAGER.</STRONG><BR /> <BR /> &nbsp;<BR /> <BR /> Let us come to RFC now and see the logic that has been implemented.<BR /> <OL><BR /> <LI>In our system, we have kept the <STRONG>Freight Order and Shipment number range same</STRONG>. Therefore, the freight order number (TOR) is same as the shipment number.</LI><BR /> <LI>Get the TOR ID in a variable. Pass it through a Conversion routine before assigning it to the internal table of type <STRONG>/SCMTMS/T_LOC_ALT_ID.</STRONG></LI><BR /> <LI>We will use the <STRONG>TOR ID as an Alternate Key</STRONG> to retrieve the Root details.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/blog5.png" height="185" width="416" /></LI><BR /> <LI>We also need to instantiate the <STRONG>Service Manager and Transaction Manager</STRONG>.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/blog6.png" /></LI><BR /> <LI>Now we retrieve the <STRONG>TOR GUID from the Freight Order Number</STRONG> and use it to fetch Root Details.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/blog7.png" /></LI><BR /> <LI>Now we pass the <STRONG>Transmission status</STRONG> and <STRONG>ERP Confirmation Date/Time</STRONG> and create the parameters for <STRONG>MODIFY Method</STRONG>. <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/blog11.png" /></LI><BR /> <LI>Pass the parameters to MODIFY method and SAVE the changes by calling the Transaction Manager.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/blog12.png" /></LI><BR /> <LI>Now we update the Carrier in the TOR structure. The challenge here is to populate the <STRONG>Action Parameters</STRONG> Declare an object of type <STRONG>/SCMTMS/S_TOR_ROOT_A_ASGN_TSP </STRONG>which is the importing parameter of the Action <STRONG>ASSIGN_TSP</STRONG>. Populate the parameter as shown below and pass it to the <STRONG>DO_ACTION method</STRONG>. <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/blog13.png" /></LI><BR /> <LI>Now we update the Status of the Freight Order (TOR). Check if the Actions mentioned above has any importing parameter. If there is, declare a <STRONG>DATA Object</STRONG> by referencing the Importing Parameter. Pass it to the <STRONG>DO_ACTION Method</STRONG> to update the carrier. <STRONG>Remember to call the Transaction manager to save the changes. <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/blog14.png" /></STRONG></LI><BR /> <LI>Except <STRONG>Logistical Execution Status</STRONG> which comes under the <STRONG>STOP Node</STRONG>, update the other status like the above steps.</LI><BR /> <LI>Update the Logistical Execution Status, get the current stop details using the <STRONG>GET_CURRENT_STOP</STRONG> method of Class <STRONG>/SCMTMS/CL_TOR_HELPER_STOP</STRONG>. <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/blog15.png" /></LI><BR /> <LI>Declare the <STRONG>Action Parameter</STRONG> by referencing the <STRONG>Importing Parameter of the Action ASSIGN_TSP. </STRONG>Pass the required values to the object. Then call the <STRONG>DO_ACTION Method.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/blog16.png" /></STRONG></LI><BR /> </OL><BR /> <H3 style="overflow: hidden;margin-bottom: 0px" id="toc-hId-893722814"><STRONG>Step 2: Call the RFC from TM System</STRONG></H3><BR /> Once the RFC has been created in TM system, the next course of action is to call the RFC from the ECC system. There are two ways to call this RFC.<BR /> <BR /> One way is to create a custom ABAP program in ECC that will call the RFC. The ABAP program will then be assigned to an Output Type that will get triggered for create/update/delete of shipment.<BR /> <BR /> Another way is to identify a BADI that will get triggered after saving of shipment and then call the RFC from the BADI.<BR /> <BR /> We will proceed with the second option here. You can choose whichever option is suitable for you. The BADI interface is <STRONG>IF_EX_BADI_LE_SHIPMENT. </STRONG>There are three methods in it – <STRONG>AT_SAVE, IN_UPDATE, BEFORE_UPDATE</STRONG>.<BR /> <BR /> We will add our logic to the <STRONG>IN_UPDATE</STRONG> Method. Implement the BADI and create an implementing class and add the below logic.<BR /> <OL><BR /> <LI>Setup RFC destination in ECC and TM system.</LI><BR /> <LI>Fetch the RFC destination and save it in a variable of type <STRONG>RFCDEST</STRONG>.</LI><BR /> <LI>Check the Importing Parameters of the Method. There are three separate internal tables for each of Shipment Related Tables. Each of the Internal Tables end with suffix like INS or UPD or DEL to distinguish between the different shipment processes like Create, Update and Delete. <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/blog8.png" /></LI><BR /> <LI>Read the Internal tables to get the Details required to update the Freight Order. Call the RFC and pass the values to the Function.</LI><BR /> <LI>There are many VTTK fields corresponding to the status as well as carrier in Freight Order in TM system. Identify the fields and pass them to the RFC.</LI><BR /> <LI><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/blog10.png" /><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/blog9.png" height="136" width="463" /><SPAN style="font-size: 1rem">This is the entire process to send data from ECC to TM system without any middleware. However, if you are using PI system as your middleware, you do not have to put in this much effort and the data flow is seamless.</SPAN>These Service Providers can get things done easily.<STRONG style="font-size: 1rem">1. </STRONG><STRONG><STRONG>TransportationOrderSCMExecutionConfirmation_In 2.TransportationOrderSCMExecutionStatusNotification_In</STRONG></STRONG><BR /> <H3 id="toc-hId-697209309"><STRONG>Conclusion</STRONG></H3><BR /> Using RFC is a simple and straightforward way to send data from one SAP system to another. It bypasses the use of middleware and can be highly effective. Check out the solution given above and let me know what you think of it.</LI><BR /> </OL> 2022-06-10T22:17:27+02:00 https://community.sap.com/t5/technology-blogs-by-members/duplicate-workitems-in-my-inbox-fiori-app/ba-p/13534631 Duplicate workitems in My Inbox fiori app 2022-06-28T08:13:23+02:00 ashar9225 https://community.sap.com/t5/user/viewprofilepage/user-id/806063 Hi,<BR /> <BR /> When you implement My Inbox fiori app you can face one issue in which user is receiving duplicate work items in his My inbox fiori app.<BR /> <BR /> If you check total workflow tasks in inbox from SBWP . Workflow is showing total 7 items.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/total7.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Total 7 workitems</P><BR /> &nbsp;<BR /> <BR /> If you login to My inbox fiori app it is showing 14.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/total-1.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Total workitems</P><BR /> In this blog we will discuss the reason behind it and how to resolve it.<BR /> <BR /> &nbsp;<BR /> <BR /> <STRONG>Reason:</STRONG><BR /> <BR /> The main reason behind it is that&nbsp; Odata service Taskprocessing&nbsp; has been assigned 2 different system aliases.<BR /> <BR /> Like follows:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/DoubkeWI1.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">System Alias</P><BR /> &nbsp;<BR /> <BR /> <STRONG>Solution:</STRONG><BR /> <BR /> Simple solution to resolve this issue is that delete one unnecessary System Alias. This will resolve the issue.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/Double2.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">System Alias</P><BR /> &nbsp;<BR /> <BR /> When you run the My Inbox Fiori app. it will show the correct number of workitems instead of showing duplicate workitems.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/06/Workitems-list.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Workitems</P><BR /> For more detail please visit&nbsp;<A href="https://community.sap.com/topics/abap" target="_blank">https://community.sap.com/topics/abap</A><BR /> <BR /> <A href="https://blogs.sap.com/" target="_blank" rel="noopener noreferrer">https://blogs.sap.com/</A><BR /> <BR /> <A href="https://community.sap.com/topics/s4hana" target="_blank">S/4 HANA Topic</A>.<BR /> <BR /> &nbsp; 2022-06-28T08:13:23+02:00 https://community.sap.com/t5/technology-blogs-by-members/creation-of-bgrfc-and-calling-in-a-program/ba-p/13569644 Creation of bgRFC and calling in a program 2023-03-15T19:38:50+01:00 MOHANVADDE https://community.sap.com/t5/user/viewprofilepage/user-id/796419 <BLOCKQUOTE><BR /> <H3 id="toc-hId-1092266079"><SPAN style="color: #000000">Description:</SPAN></H3><BR /> <OL><BR /> <LI><BR /> <H4 id="toc-hId-1024835293"><SPAN style="color: #000000">What is bgRFC.</SPAN></H4><BR /> </LI><BR /> <LI><BR /> <H4 id="toc-hId-828321788"><SPAN style="color: #000000">bgRFC configuration.</SPAN></H4><BR /> </LI><BR /> <LI><BR /> <H4 id="toc-hId-631808283"><SPAN style="color: #000000">bgRFC programming.</SPAN></H4><BR /> </LI><BR /> <LI><BR /> <H4 id="toc-hId-435294778"><SPAN style="color: #000000">bgRFC Monitoring.</SPAN></H4><BR /> </LI><BR /> </OL><BR /> &nbsp;<BR /> <H3 id="toc-hId-109698554"><STRONG>1. What is bgRFC?</STRONG></H3><BR /> The bgRFC allows application to record data that is received later by a called<BR /> <BR /> application. When the data is received, we must ensure that the data was transferred to<BR /> <BR /> the receiver either once only in any order(transactional) or once only in the order of<BR /> <BR /> creation(queued).<BR /> <BR /> &nbsp;<BR /> <H3 id="toc-hId--86814951">2. bgRFC Configuration?</H3><BR /> <UL><BR /> <LI><BR /> <H4 id="toc-hId--154245737">Creation of supervisor Destination.</H4><BR /> </LI><BR /> </UL><BR /> This is a mandatory step because the bgRFC can only function if a supervisor<BR /> <BR /> destination has been define for bgRFC processing. For creation of supervisor<BR /> <BR /> destination the t-code is <STRONG><EM>SBGRFCCONF</EM></STRONG>.<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Configuration_1.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Configuration_1</P><BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Configuration_2.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Configuration_2</P><BR /> <BR /> <H3 id="toc-hId--479841961">Prerequisite:</H3><BR /> Need to verify the supervisor destination as an RFC destination using the transaction<BR /> <BR /> <EM><STRONG> SM59</STRONG></EM>. This destination must be defined as either an ABAP connection or a logical<BR /> <BR /> connection.<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Configuration_3.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Configuration_3</P><BR /> A user, password, and client must be entered for both connection types. Please refer<BR /> <BR /> the attached screenshot.<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Configuration_4.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Configuration_4</P><BR /> <BR /> <H3 id="toc-hId--676355466">ABAP Connection :</H3><BR /> No load balancing can be defined.<BR /> <BR /> No system number can be entered.<BR /> <BR /> No server can be entered.<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Configuration_5.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Configuration_5</P><BR /> <BR /> <H3 id="toc-hId--948100340"><STRONG>Creation of destination:</STRONG></H3><BR /> We have to create inbound/outbound destination name based on the requirement.<BR /> <BR /> &nbsp;<BR /> <BR /> <STRONG>Creation of Inbound Destination:</STRONG><BR /> <BR /> On the define inbound Dest. Tab page in the transaction <EM><STRONG><SPAN style="color: #000000">SBGRFCCONF</SPAN></STRONG></EM>, we can<BR /> <BR /> maintain a separate inbound destination for each application. This is also mandatory<BR /> <BR /> step to create any inbound bgRFC.<BR /> <BR /> &nbsp;<BR /> <BR /> Logon/Server group can be defined using transaction <EM><STRONG>RZ12</STRONG></EM>.<BR /> <BR /> &nbsp;<BR /> <BR /> All the settings and activities related to the transaction <EM><STRONG>SBGRFCCONF</STRONG></EM> is BASIS related<BR /> <BR /> activity so before creating/configuring any bgRFC please consult with BASIS team.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Configuration_6.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Configuration_6</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Configuration_7.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Configuration_7</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Configuration_8.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Configuration_8</P><BR /> &nbsp;<BR /> <H4 id="toc-hId--1438016852"><STRONG>Creation of outbound destination:</STRONG></H4><BR /> We can create outbound destination using transaction <EM><STRONG>SM59</STRONG></EM>. Creation of outbound<BR /> <BR /> destination in <EM><STRONG>SM59</STRONG></EM> is normal like any of the destination creation. Please refer the<BR /> <BR /> below screenshot for reference.<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Configuration_9.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Configuration_9</P><BR /> &nbsp;<BR /> <BR /> We have to created outbound destination under ABAP Connections. For this destination<BR /> <BR /> we have to maintain the necessary target destination IP, system no etc. Please refer all<BR /> <BR /> the below screenshots for detailed setting in each tab.<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Configuration_10.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Configuration_10</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Configuration_11.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Configuration_11</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Configuration_12.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Configuration_12</P><BR /> &nbsp;<BR /> <BR /> After creation of the outbound destination in <EM><STRONG>SM59</STRONG></EM> we have to maintain this destination<BR /> <BR /> in <EM><STRONG>SBGRFCCONF</STRONG></EM> transaction. We have to maintain the destination in Scheduler<BR /> <BR /> Destination tab of transaction <EM><STRONG>SBGRFCCONF</STRONG></EM>. Please refer the below screenshot.<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Configuration_13.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Configuration_13</P><BR /> &nbsp;<BR /> <H3 id="toc-hId--1341127350">3. bgRFC Programming</H3><BR /> After the entire configuration now let’s talk about the programming.<BR /> <BR /> &nbsp;<BR /> <UL><BR /> <LI><BR /> <H4 id="toc-hId--1831043862">Creation of unit:</H4><BR /> </LI><BR /> </UL><BR /> We have to create one bgRFC unit by taking the reference from the configured<BR /> <BR /> inbound/outbound destination name. Destination objects can be requested using the<BR /> <BR /> class methods from the class CL_BGRFC_DESTINATION_OUTBIUND for the<BR /> <BR /> outbound and the class CL_BGRFC_DESTINATION_INBOUND for the inbound. We<BR /> <BR /> have to use method create of the above mentioned class to create a destination object.<BR /> <BR /> Please see the below example of how to create an inbound destination object.<BR /> <BR /> &nbsp;<BR /> <BR /> Pass any of the configured inbound destination name in the below mentioned variable.<BR /> <BR /> &nbsp;<BR /> <BR /> Call the below mentioned method to create reference of inbound destination.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Programming_1.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Programming_1</P><BR /> &nbsp;<BR /> <BR /> If the inbound/outbound destine is invalid the program is going to dump.<BR /> <BR /> Please refer the blow screen shot for your reference.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Programming_2.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Programming_2</P><BR /> &nbsp;<BR /> <BR /> For handling the runtime error we need to use exception class<BR /> <BR /> <EM><STRONG>CX_BGRFC_INVALID_DESTINATION</STRONG></EM>. Please refer the below screenshot for your<BR /> <BR /> reference.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Programming_3.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Programming_3</P><BR /> &nbsp;<BR /> <P style="text-align: left">After creation of the destination object it is time to create a bgRFC unit. bgRFC unite</P><BR /> <P style="text-align: left">can be two types like tRFC and qRFC. We have to use method <EM><STRONG>CREATE_TRFC_UNIT</STRONG></EM></P><BR /> <P style="text-align: left">to create a tRFC unit and method <EM><STRONG>CREATE_QRFC_UNIT</STRONG></EM> to create a qRFC unit. Please</P><BR /> <P style="text-align: left">refer the below screenshot.</P><BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Programming_4.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Programming_4</P><BR /> &nbsp;<BR /> <BR /> To create a qRFC unit we just have to call <EM><STRONG>CREATE_QRFC_UNIT</STRONG></EM> method instead of<BR /> <BR /> <EM><STRONG>CREATE_TRFC_UNIT</STRONG></EM> method.<BR /> <BR /> &nbsp;<BR /> <H3 id="toc-hId--1734154360">Calling a function module:</H3><BR /> After creation of the unit we have to call any function module in background. The new<BR /> <BR /> syntax for calling a function module for background processing is as follows.<BR /> <BR /> &nbsp;<BR /> <BR /> <EM><STRONG>CALL FUNTION ‘function_name’</STRONG></EM><BR /> <BR /> <EM><STRONG>IN BACKGROUND UNIT unit</STRONG></EM><BR /> <BR /> <EM><STRONG>EXPORTING…</STRONG></EM><BR /> <BR /> Inside the calling function module we have to write our required logic which we want to<BR /> <BR /> process in background (e.g Update a table). Please refer below screenshot for calling of<BR /> <BR /> a function module.<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Programming_5.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Programming_5</P><BR /> &nbsp;<BR /> <BR /> In the above example the function module is called in background using the created<BR /> <BR /> unit. In the exporting parameter we can define whatever we want to send in the function<BR /> <BR /> module. If we want to send some table also we can define it in the calling module and<BR /> <BR /> we can send it.<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Programming_6.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Programming_6</P><BR /> &nbsp;<BR /> <BR /> The above screenshot shows complete program to call bgRFC.<BR /> <BR /> &nbsp;<BR /> <H3 id="toc-hId--1930667865">RFC Function module:</H3><BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/RFC_Fun.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">RFC_Fun_1</P><BR /> &nbsp;<BR /> <BR /> The function module must be RFC enabled function module.<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/RFC_Fun_1.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">RFC_Fun_2</P><BR /> &nbsp;<BR /> <BR /> Here one thing need to remembered, calling the function module will happen once<BR /> <BR /> program does the COMMIT WORK. If we want to create bgRFC from our custom<BR /> <BR /> program like report in that case we have to do external COMMIT WORK but if we are<BR /> <BR /> trying to create bgRFC from any BADI/USER EXIT/Enhancement Spot in that case we<BR /> <BR /> do not need to apply external COMMIT WORK. Once standard SAP do the COMMIT<BR /> <BR /> WORK bgRFC unit will be Created.<BR /> <BR /> &nbsp;<BR /> <H3 id="toc-hId--2127181370">4. bgRFC Monitoring:</H3><BR /> bgRFC monitor typically required to check if any unit is failed or there are any issue in<BR /> <BR /> any particular unit.<BR /> <BR /> &nbsp;<BR /> <BR /> We have to use transaction <EM><STRONG>SBGRFCMON</STRONG></EM> to monitor bgrfc unit. In the selection screen<BR /> <BR /> we have option to monitor Inbound/Outbound unit along with tRFC unit or qRFC unit.<BR /> <BR /> Also there are several options in the selection screen. Please refer the below screen shot.<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Mon_1.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Mon_1</P><BR /> &nbsp;<BR /> <BR /> After execution the transaction we will be able to monitor all the erroneous units in the<BR /> <BR /> system. We have to remember if any unit is created successfully and if there are no<BR /> <BR /> data issue or any connection issue in that case it will be executed and we will not able<BR /> <BR /> to see it in this transaction. Only erroneous and warning units will be displayed here.<BR /> <BR /> Please refer the below screenshot.<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/03/bgRFC_Mon_2.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">bgRFC_Mon_2</P><BR /> <BR /> <H3 id="toc-hId-1971272421"><STRONG><U>Conclusion:</U></STRONG></H3><BR /> Background Remote Funtion Call (bgRFC) is a technology in SAP that allow for<BR /> <BR /> asynchronous (qRFC) and synchronously (tRFC) communication between different<BR /> <BR /> systems. It is used to enable background processing of distributed system in a secure<BR /> <BR /> and reliable manner.<BR /> <BR /> &nbsp;<BR /> <BR /> With bgRFC, developers can create and schedule processes to run in the background<BR /> <BR /> of SAP system, which helps reduce the workload on the front-end and improve system<BR /> <BR /> performance.&nbsp; The technology ensure that all data is transmitted securely and can<BR /> <BR /> handle large volumes of data efficiently.<BR /> <BR /> &nbsp;<BR /> <BR /> I would like to hear your thoughts and feedback on this post and promoting relevant<BR /> <BR /> community resources in the SAP community.<BR /> <BR /> &nbsp;<BR /> <H3 id="toc-hId-1774758916"><STRONG><U>Related links </U></STRONG></H3><BR /> Other Blogs for related bgRFC:<BR /> <BR /> <A href="https://support.sap.com/en/alm/sap-focused-run/expert-portal/integration-cloud-monitoring/bgrfc.html#:~:text=bgRFC%20is%20a%20superordinate%20term,classic%20tRFC%20and%20qRFC%20versions" target="_blank" rel="noopener noreferrer">https://support.sap.com/en/alm/sap-focused-run/expert-portal/integration-cloud-monitoring/bgrfc.html#:~:text=bgRFC%20is%20a%20superordinate%20term,classic%20tRFC%20and%20qRFC%20versions</A>.<BR /> <BR /> <A href="https://support.sap.com/en/alm/solution-manager/expert-portal/monitoring-of-integration-scenarios/bgrfc-channel.html" target="_blank" rel="noopener noreferrer">https://support.sap.com/en/alm/solution-manager/expert-portal/monitoring-of-integration-scenarios/bgrfc-channel.html</A><BR /> <BR /> &nbsp;<BR /> <H3 id="toc-hId-1578245411"><STRONG><U>More Blogs:</U></STRONG></H3><BR /> <A href="https://community.sap.com/topics/abap-connectivity" target="_blank">https://community.sap.com/topics/abap-connectivity</A><BR /> <BR /> <A href="https://answers.sap.com/tags/266264953119842772207986043063520" target="_blank" rel="noopener noreferrer">https://answers.sap.com/tags/266264953119842772207986043063520</A><BR /> <BR /> <A href="https://blogs.sap.com/tags/266264953119842772207986043063520/" target="_blank" rel="noopener noreferrer">https://blogs.sap.com/tags/266264953119842772207986043063520/</A><BR /> <BR /> &nbsp;<BR /> <BR /> Thank you for reading my content on SCN blog! If you enjoyed what you read and<BR /> <BR /> would like to see more, I encourage you to follow my profile.<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;</BLOCKQUOTE> 2023-03-15T19:38:50+01:00 https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/sap-build-apps-and-bapis-rfc-meets-web/ba-p/13555549 SAP Build Apps and BAPIs: RFC meets Web 2023-04-02T12:17:56+02:00 Gunter https://community.sap.com/t5/user/viewprofilepage/user-id/727 <H2 id="toc-hId-962139719"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/スクリーンショット-2023-04-02-164241.jpg" /><EM>"RFC meets Web"</EM></H2><BR /> <H3 id="toc-hId-894708933">Enable all your RFC functions for web consumption without development?</H3><BR /> Today, I'm excited to share a new thing: A proxy on SAP BTP that translates from REST to SAP RFC calls, making it possible to use BAPIs and RFC-enabled function modules on <STRONG>older SAP ECC</STRONG> or S/4HANA systems.<BR /> <BR /> This solution is particularly useful for SAP ERP users who are looking to integrate with systems that lack the new OData APIs that are only available on newer S/4HANA systems. With the REST-to-RFC proxy, RFC meets web, creating a seamless integration experience that unlocks the full potential of your SAP ecosystem.<BR /> <BR /> <STRONG>Benefits:</STRONG><BR /> <UL><BR /> <LI>Protect your past investment: Use your function modules for the web</LI><BR /> <LI>RFC modules turned into synchronous REST APIs</LI><BR /> <LI>No further development work</LI><BR /> <LI>Secured communication through SAP BTP destinations</LI><BR /> </UL><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/スクリーンショット-2023-04-02-160900-1.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 1: Outline of solution - it works with any RFC function module (Y/Z-RFC modules included)</P><BR /> In this blog post, we'll take a closer look at how this proxy works, the benefits it provides, and the impact it can have on your SAP integration projects. So, let's dive in and discover the possibilities of web meets RFC!<BR /> <H2 id="toc-hId-569112709">Solution approach</H2><BR /> SAP BTP offers the destination service to define ways to connect to systems. Keeping destinations separate from applications makes them reusable and easy to maintain. They come in several flavors like:<BR /> <OL><BR /> <LI>HTTP - for anything like REST, OData-REST, HTML and the like.</LI><BR /> <LI>LDAP - Lightweight Directory Access Protocol to lookup information in a network. Often used for organizational data of entities and persons.</LI><BR /> <LI>MAIL - to send emails to an SMTP server</LI><BR /> <LI>RFC - Remote Function Call, this is what we look at for the cloud connector-facing side.</LI><BR /> </OL><BR /> From here we define the first destination to the <A href="https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/cloud-connector" target="_blank" rel="noopener noreferrer">cloud connector</A> (CC) as RFC. You need to white-list the function modules you plan to use in your cloud connector instance.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/スクリーンショット-2023-04-02-165040.jpg" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 2: Example of an RFC destination. The ashost is as defined in your CC.</P><BR /> I use this destination in the Java HTTPServlet. On the consumption side you'll need another destination that you can use for e.g. SAP Build Apps and which is provided by the HTTPServlet. If you secure it with OAuth2 the config could look like that.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/スクリーンショット-2023-04-02-165543.jpg" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 3: REST destination for consumption of BAPIs or RFC functions in general.</P><BR /> Since I use xsuaa for authentication and authorization I've defined 2 scopes to allow for display and change authorization.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/スクリーンショット-2023-04-02-170311.jpg" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 4: POST and GET related scopes to be assigned to relevant users for consumption.</P><BR /> The difference between the two is that the POST will trigger a BAPI.commit and therefore posts data in your S/4HANA or ECC system while the GET doesn't. Of course it depends on how you've designed your ABAP code - standard BAPIs will adhere to this approach.<BR /> <H2 id="toc-hId-372599204">SAP Build Apps demo: Change material master</H2><BR /> Enough talk! Let's see a demo built with SAP Build Apps. It uses 3 BAPIs:<BR /> <OL><BR /> <LI>BAPI_MATERIAL_GETLIST - To search for materials and get them in a list</LI><BR /> <LI>BAPI_MATERIAL_GETALL - To retrieve the details of a selected material</LI><BR /> <LI>BAPI_MATERIAL_SAVEDATA - To change some fields in the material master</LI><BR /> </OL><BR /> There is no development done on both backend and frontend.<BR /> <H3 id="toc-hId-305168418">1. Mobile application</H3><BR /> <IFRAME id="kaltura_player_1_p5s5dr9z" src="https://sapvideoa35699dc5.hana.ondemand.com/?entry_id=1_2wkpiuv2" allowfullscreen="true" webkitallowfullscreen="" mozallowfullscreen="" width="625px" height="360px" frameborder="0"></IFRAME><BR /> <H3 id="toc-hId-108654913">2. SAP Build and S/4HANA Backend</H3><BR /> <IFRAME id="kaltura_player_1_p5s5dr9z" src="https://sapvideoa35699dc5.hana.ondemand.com/?entry_id=1_upydyozz" allowfullscreen="true" webkitallowfullscreen="" mozallowfullscreen="" width="625px" height="360px" frameborder="0"></IFRAME><BR /> <H2 id="toc-hId--216941311">Solution Architecture</H2><BR /> Below are the schematics for using the REST to RFC proxy running on BTP Cloud Foundry.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/スクリーンショット-2023-04-01-220657-1.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 2: Solution architecture for REST-RFC proxy on SAP BTP Cloud Foundry</P><BR /> I'll explain the technical details in a second blog if you are interested to create such a proxy on BTP for yourself.<BR /> <H2 id="toc-hId--413454816">Conclusion</H2><BR /> And there it is: A proxy that opens all your RFC developments to the web in a secured manner. Hope it is useful!<BR /> <BR /> Check my <A href="https://blogs.sap.com/2023/04/04/rfc-meets-the-web-building-the-proxy/" target="_blank" rel="noopener noreferrer">second blog</A> for the technical details on how you can design the proxy on SAP BTP. 2023-04-02T12:17:56+02:00 https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/rfc-meets-the-web-part-ii-building-the-proxy/ba-p/13566876 RFC meets the Web: Part II - Building the proxy 2023-04-04T03:19:14+02:00 Gunter https://community.sap.com/t5/user/viewprofilepage/user-id/727 <H2 id="toc-hId-963096004"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/スクリーンショット-2023-04-04-101621.jpg" /></H2><BR /> <H2 id="toc-hId-766582499"><EM>RFC meets Web - Part II: How to build the proxy</EM></H2><BR /> Welcome back to the second blog post where we look into building the REST2RFC proxy! It's a SAP Cloud SDK Java application running on SAP BTP Cloud Foundry runtime.<BR /> <H2 id="toc-hId-570068994">Introduction and BTP services used</H2><BR /> When I started with the project (which was inspired by customers telling me "we don't have APIs, we are still on S/4HANA 1909") I explored the options to build a proxy to translate between the RFC and the REST world. A few things became clear:<BR /> <UL><BR /> <LI>That proxy must be agnostic - no function module specific logic should be in it, so it can be universal.</LI><BR /> <LI>REST is channeled through SAP Cloud Connector and with that we have a granular way to white-list what should be exposed from the on-premise system.</LI><BR /> <LI>SAP BTP offers the RFC-flavor for defining a destination. Great!</LI><BR /> <LI>Using BTP RFC destinations only works through Java and the <A href="https://mvnrepository.com/artifact/com.sap.cloud/neo-java-web-api" target="_blank" rel="nofollow noopener noreferrer">API For SAP BTP (Java Web Tomcat 9)</A> which is not in the <A href="https://sap.github.io/cloud-sdk/docs/java/getting-started" target="_blank" rel="nofollow noopener noreferrer">SAP Cloud SDK for Java</A> (not to be confused with the <A href="https://support.sap.com/en/product/connectors/jco.html" target="_blank" rel="noopener noreferrer">JCo you can download</A> as a separate package) and likely coming from Neo but working perfectly fine with CF and latest Cloud SDK, too.</LI><BR /> <LI>All existing tutorials were outdated that explained the RFC integration so I hope this blog helps you.</LI><BR /> </UL><BR /> As for the BTP project building the application needs these services:<BR /> <OL><BR /> <LI><STRONG>Authorization and Trust Management Service (xsuaa)</STRONG>: Securing the application from the web entry point with OAuth2 and roles to be assigned to a user which define the scope during authentication as part of the JWT.</LI><BR /> <LI><STRONG>Connectivity Service</STRONG>: To connect between cloud and on-premise through the Cloud Connector (CC).</LI><BR /> <LI><STRONG>Destination Service</STRONG>: To retrieve the destinations in the Java app for RFC and offer the REST service to the caller.</LI><BR /> <LI><STRONG>Application Logging Service</STRONG>: To allow for a really nice monitoring of the proxy. Not mandatory but I highly recommend it for debugging and day-to-day monitoring.</LI><BR /> </OL><BR /> <H2 id="toc-hId-373555489">Proxy project details</H2><BR /> <H3 id="toc-hId-306124703">Development IDE</H3><BR /> I used Eclipse in connection with the SAP Cloud SDK for Java. You want to install Maven with<BR /> <PRE class="language-c"><CODE>$ choco install maven</CODE></PRE><BR /> on a Windows device. To create a fresh project I ran<BR /> <PRE class="language-c"><CODE>mvn archetype:generate "-DarchetypeGroupId=com.sap.cloud.sdk.archetypes" "-DarchetypeArtifactId=scp-cf-tomee" "-DarchetypeVersion=RELEASE"</CODE></PRE><BR /> since I built on TomcatEE and not Springboot. This create the framework you should open in Eclipse once done.<BR /> <BR /> I deleted those elements which I didn't need (like junit and integration tests <span class="lia-unicode-emoji" title=":face_with_tears_of_joy:">😂</span>) so the build process just considered my code. You also need to define a manifest file and the obligatory xs-security.json.<BR /> <PRE class="language-c"><CODE>---<BR /> applications:<BR /> <BR /> - name: jco-rfc-rest-server<BR /> memory: 1500M<BR /> timeout: 300<BR /> random-route: true<BR /> path: application/target/jco-rfc-rest-server-application.war<BR /> buildpacks:<BR /> - sap_java_buildpack<BR /> env:<BR /> USE_JCO: "true"<BR /> TARGET_RUNTIME: tomee7<BR /> SET_LOGGING_LEVEL: '{ROOT: INFO, com.sap.cloud.sdk: INFO}'<BR /> JBP_CONFIG_SAPJVM_MEMORY_SIZES: 'metaspace:128m..'<BR /> xsuaa_connectivity_instance_name: "jco-rfc-rest-server-xsuaa"<BR /> connectivity_instance_name: "jco_connectivity"<BR /> destination_instance_name: "jco_destination"<BR /> ENABLE_SECURITY_JAVA_API_V2: "true"<BR /> <BR /> services:<BR /> - jco-rfc-rest-server-xsuaa<BR /> - jco_connectivity<BR /> - jco_destination<BR /> - jco-app-logging</CODE></PRE><BR /> above is my manifest.yml.<BR /> <PRE class="language-javascript"><CODE>{<BR /> "xsappname": "jco-rfc-rest-server",<BR /> "tenant-mode": "dedicated",<BR /> "scopes": [<BR /> {<BR /> "name": "$XSAPPNAME.Display",<BR /> "description": "GET requests on BAPI"<BR /> },<BR /> {<BR /> "name": "$XSAPPNAME.Modify",<BR /> "description": "POST requests on BAPI"<BR /> }<BR /> ],<BR /> "role-templates": [<BR /> {<BR /> "name": "JCo-REST-RFC-Server-Viewer",<BR /> "description": "Required to run GET requests for RFC BAPI calls.",<BR /> "scope-references" : [<BR /> "$XSAPPNAME.Display"<BR /> ]<BR /> },<BR /> {<BR /> "name": "JCo-REST-RFC-Server-Administrator",<BR /> "description": "Required to run POST requests for RFC BAPI calls.",<BR /> "scope-references" : [<BR /> "$XSAPPNAME.Modify"<BR /> ]<BR /> }<BR /> ]<BR /> }</CODE></PRE><BR /> Above is my xs-security.json. Based on that you can create 2 role collections in BTP later to allow for a display and and admin role for the proxy calls.<BR /> <H3 id="toc-hId-109611198">Java specifics: Authority checks</H3><BR /> The Java class for the proxy is based on the <EM>HttpServlet</EM> class. Below I'd like to share the pattern for authority checks.<BR /> <PRE class="language-java"><CODE>@WebServlet("/rfc/*")<BR /> @ServletSecurity(@HttpConstraint(rolesAllowed = { "Display", "Modify" }))<BR /> public class Rest2RfcProxy extends HttpServlet {<BR /> <BR /> // .... some code<BR /> <BR /> @Override<BR /> @RolesAllowed({"Modify"})<BR /> protected void doPost(HttpServletRequest request, HttpServletResponse response)<BR /> throws ServletException, IOException { <BR /> // ...<BR /> }<BR /> <BR /> @Override<BR /> @RolesAllowed({"Display", "Modify"})<BR /> protected void doGet(HttpServletRequest request, HttpServletResponse response)<BR /> throws ServletException, IOException {<BR /> // ...<BR /> }<BR /> <BR /> // .... some more code<BR /> <BR /> }</CODE></PRE><BR /> So that's how the security scopes defined in <EM>xs-security.json</EM> are checked in the Java code. You must enable that in the <EM>web.xml</EM> file of the webapp like so:<BR /> <PRE class="language-markup"><CODE> &lt;login-config&gt;<BR /> &lt;auth-method&gt;XSUAA&lt;/auth-method&gt;<BR /> &lt;/login-config&gt;<BR /> <BR /> &lt;security-constraint&gt;<BR /> &lt;web-resource-collection&gt;<BR /> &lt;web-resource-name&gt;Baseline Security&lt;/web-resource-name&gt;<BR /> &lt;url-pattern&gt;/*&lt;/url-pattern&gt;<BR /> &lt;/web-resource-collection&gt;<BR /> &lt;auth-constraint&gt;<BR /> &lt;role-name&gt;*&lt;/role-name&gt;<BR /> &lt;/auth-constraint&gt;<BR /> &lt;/security-constraint&gt;<BR /> <BR /> &lt;security-role&gt;<BR /> &lt;role-name&gt;Display&lt;/role-name&gt;<BR /> &lt;/security-role&gt;<BR /> &lt;security-role&gt;<BR /> &lt;role-name&gt;Modify&lt;/role-name&gt;<BR /> &lt;/security-role&gt;</CODE></PRE><BR /> Only then it will work with the data injected by the JWT.<BR /> <BR /> Info: Per default BTP destination service will work with X-CSRF token. I turned it off for testing - this is also defined in <EM>web.xml</EM>!<BR /> <H3 id="toc-hId--86902307">Java specifics: JCo REST/RFC</H3><BR /> The communication through JCo via RFC follows this sequence:<BR /> <OL><BR /> <LI>Get the RFC destination with details that we specified in the SAP BTP (see the <A href="https://blogs.sap.com/2023/04/02/sap-build-apps-and-bapis-rfc-meets-web/" target="_blank" rel="noopener noreferrer">first blog</A>).</LI><BR /> <LI>Define the function to be called in Java.</LI><BR /> <LI>Define the import/ export and table parameter list from the function module. These variables hold the according structures.</LI><BR /> <LI>Load the metadata of the 3 objects from the SAP ECC or S/4HANA data dictionary.</LI><BR /> <LI>Set the import or tables parameters as needed.</LI><BR /> <LI>Execute the function module call.</LI><BR /> <LI>If it's a POST, also execute a call to BAPI BAPI_TRANSACTION_COMMIT. If you call a Z-function module it depends how your organized your LUW whether this has any impact at all. Certainly it won't hurt but the commit might have been done before that in your ABAP code.</LI><BR /> <LI>Feed back the data to the caller</LI><BR /> </OL><BR /> Example for the IMPORTS:<BR /> <PRE class="language-java"><CODE>if (jImports != null) {<BR /> logger.info("Filling BAPI import: " + jImports.toString());<BR /> bapiImports.getMetaData();<BR /> bapiImports.fromJSON(jImports.toString());<BR /> }</CODE></PRE><BR /> This uses the <EM>.fromJSON</EM> method to fill the structure. On the way back to the caller you can then use the <EM>.toJSON</EM> method to obtain the JSON data for REST.<BR /> <H3 id="toc-hId--283415812">Application logging</H3><BR /> I recommend to consider using the application logging service on BTP, particularly for this middleware application to facilitate error analysis. It builds on the common org.slf4j framework. You activate it with<BR /> <PRE class="language-java"><CODE>private static final Logger logger = LoggerFactory.getLogger(&lt;your class name&gt;.class);</CODE></PRE><BR /> declared on class level to have it available in every method and exception. In the manifest.yml you can then set the logging level:<BR /> <PRE class="language-abap"><CODE>SET_LOGGING_LEVEL: '{ROOT: INFO, com.sap.cloud.sdk: INFO}'</CODE></PRE><BR /> here it means everything is logged. You can reduce it to WARN or ERROR.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/スクリーンショット-2023-04-03-090730.jpg" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 1: Application Logging service on BTP</P><BR /> The dashboard offers detailed filtering and statistics which are very handy.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/スクリーンショット-2023-04-03-091021.jpg" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 2: Application logging dashboard overview</P><BR /> <BR /> <H2 id="toc-hId--609012036">Troubleshooting</H2><BR /> I faced a few issues when developing and building it because the tutorials were outdated or didn't support the use case. Maybe this can help you.<BR /> <H3 id="toc-hId--676442822">java.lang.UnsupportedClassVersionError</H3><BR /> <EM>"java.lang.UnsupportedClassVersionError: com/sap/demo/jco/ConnectivityRFCExample has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 52.0 (unable to load class [com.sap.demo.jco.ConnectivityRFCExample])</EM><BR /> <BR /> This means the bytecode of the WAR file isn't matching the BTP Java Buildpack. First you want to check the buildpack on BTP:<BR /> <PRE class="language-abap"><CODE>$ cf buildpacks</CODE></PRE><BR /> E.g. 52.0 = Java 8, 61.0 = Java 17. I had to set my Eclipse JDK to create code for 52.0 by setting it to Java 8 from Java 17. Also this <A href="https://help.sap.com/docs/btp/sap-business-technology-platform/developing-java-cloud-foundry-environment" target="_blank" rel="noopener noreferrer">help</A> is useful (standard is Java 8, if using SAP Machine it's Java 11).<BR /> <H3 id="toc-hId--948187696">POST, PUT, PATCH. DELETE will require X-CSRF-Token</H3><BR /> If you don't want that, turn it off, out-comment the section for the filter RestCsrfPreventionFilter in web.xml. This can help during testing. For production, better put it back in.<BR /> <H3 id="toc-hId--1144701201">After setting up a fresh project with Maven Eclipse looks "funny"</H3><BR /> You got to switch the facet in the project properties to Java.<BR /> <H3 id="toc-hId--1341214706">Maven repository not found</H3><BR /> Add it to the Java Build Path in the project's properties.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/スクリーンショット-2023-04-03-092209.jpg" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 3: Project properties, Java build path</P><BR /> <BR /> <H3 id="toc-hId--1537728211">"Where is the source code?"</H3><BR /> Please check my LinkedIn post in that matter.<BR /> <H2 id="toc-hId--1440838709">Conclusion</H2><BR /> Building a proxy to translate between the RFC and REST world requires an agnostic proxy. It is a universal solution without function module specific logic, and the REST service is channeled through the SAP Cloud Connector. Using the RFC-flavor for defining a destination on the SAP BTP platform with Java Web Tomcat 9 API allowed for easy integration. By following this blog, building an efficient proxy is now possible, and it will be useful for businesses using older SAP S/4HANA or ECC systems.<BR /> <BR /> Let me know your feedback - I'm eager to learn how you are using the approach for your web use cases!<BR /> <BR /> &nbsp; 2023-04-04T03:19:14+02:00 https://community.sap.com/t5/technology-blogs-by-members/parallel-processing-on-oabap-using-classes-and-methods/ba-p/13557161 Parallel Processing On OABAP - Using Classes and Methods 2023-04-27T18:03:43+02:00 Shruthisampath https://community.sap.com/t5/user/viewprofilepage/user-id/128334 &nbsp;<BR /> <BR /> Parallel processing is implemented in ABAP reports and programs, not in the background processing system itself. That means that jobs are only processed in parallel if the report that runs in a job step is programmed for parallel processing. Such reports can also process in parallel if they are started interactively.<BR /> <BR /> Parallel processing in OAbap is using class and methods in report level program.<BR /> <BR /> Parallel Processing is implemented with a special variant of Asynchronous RFC. It’s important that you use only the correct variant for you own parallel processing applications. The <STRONG>“CALL FUNCTION STARTING NEW TASK DESTINATION IN GROUP”</STRONG> keywords.<BR /> <BR /> when a huge number of records needs to be processed and it takes a lot of time to produce the output, this parallel processing technique can be applied to achieve run time improvement. So, this Parallel processing is an asynchronous call to the Function Module in parallel sessions/ different session/ multiple sessions<STRONG>.</STRONG><BR /> <BR /> T-Codes:<BR /> <BR /> RZ12 - To Check the Server Group.<BR /> <BR /> SM66 - To Check all the Work Processers.<BR /> <BR /> SM51 - To Check the Application Server.<BR /> <BR /> SM21 - System log in case of any failures.<BR /> <BR /> &nbsp;<BR /> <BR /> """"" parallel processing """"""""<BR /> <BR /> <!--StartFragment --><SPAN class="L0S52">REPORT&nbsp;</SPAN>ZPARALLEL_PROCESSING_OABAP<SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">DATA</SPAN><SPAN class="L0S55">:</SPAN>chk1<SPAN class="L0S55">,</SPAN><BR /> chk2<SPAN class="L0S55">,</SPAN><BR /> ret11 <SPAN class="L0S52">TYPE&nbsp;</SPAN><SPAN class="L0S52">TABLE&nbsp;</SPAN><SPAN class="L0S52">Of&nbsp;</SPAN>bapisdstat<SPAN class="L0S55">,</SPAN><BR /> ret22 <SPAN class="L0S52">TYPE&nbsp;</SPAN><SPAN class="L0S52">TABLE </SPAN><SPAN class="L0S52">OF&nbsp;</SPAN>bapisdstat<SPAN class="L0S55">,</SPAN><BR /> ret <SPAN class="L0S52">TYPE&nbsp;</SPAN>bapisdstat<SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">CLASS&nbsp;</SPAN>lcl_demo&nbsp;<SPAN class="L0S52">DEFINITION</SPAN><SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">PUBLIC&nbsp;</SPAN><SPAN class="L0S52">SECTION</SPAN><SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">CLASS-METHODS</SPAN><SPAN class="L0S55">:&nbsp; &nbsp; </SPAN><BR /> <BR /> <SPAN class="L0S52">CALL </SPAN><SPAN class="L0S52">IMPORTING&nbsp;</SPAN>sdoc1&nbsp;<SPAN class="L0S52">TYPE&nbsp;</SPAN>bapivbeln<SPAN class="L0S70">-</SPAN>vbeln<BR /> sdoc2 <SPAN class="L0S52">TYPE&nbsp;</SPAN>bapivbeln<SPAN class="L0S70">-</SPAN>vbeln<SPAN class="L0S55">,</SPAN><BR /> handle1&nbsp;<SPAN class="L0S52">IMPORTING&nbsp;</SPAN>p_task&nbsp;<SPAN class="L0S52">TYPE&nbsp;</SPAN>clike<SPAN class="L0S55">,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</SPAN><SPAN class="L0S31">"must&nbsp;have&nbsp;a&nbsp;importing&nbsp;para-of&nbsp;type&nbsp;clike</SPAN><BR /> handle2&nbsp;<SPAN class="L0S52">IMPORTING&nbsp;</SPAN>p_task&nbsp;<SPAN class="L0S52">TYPE&nbsp;</SPAN>clike<SPAN class="L0S55">.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</SPAN><SPAN class="L0S31">"must&nbsp;have&nbsp;a&nbsp;importing&nbsp;para-of&nbsp;type&nbsp;clike</SPAN><BR /> <BR /> <SPAN class="L0S52">ENDCLASS</SPAN><SPAN class="L0S55">.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </SPAN><SPAN class="L0S31">"LCL_DEMO DEFINITION</SPAN><BR /> <BR /> <SPAN class="L0S31">*———————————————————————-*</SPAN><BR /> <BR /> <SPAN class="L0S31">*       CLASS LCL_DEMO IMPLEMENTATION</SPAN><BR /> <BR /> <SPAN class="L0S31">*———————————————————————-*</SPAN><BR /> <BR /> <SPAN class="L0S52">CLASS&nbsp;</SPAN>lcl_demo&nbsp;<SPAN class="L0S52">IMPLEMENTATION</SPAN><SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">METHOD&nbsp;</SPAN><SPAN class="L0S52">call</SPAN><SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">CALL&nbsp;</SPAN><SPAN class="L0S52">FUNCTION</SPAN><SPAN class="L0S33">'BAPI_SALESORDER_GETSTATUS'</SPAN><BR /> <SPAN class="L0S52">STARTING&nbsp;</SPAN><SPAN class="L0S52">NEW&nbsp;</SPAN><SPAN class="L0S52">TASK</SPAN><SPAN class="L0S33">'FUNC1'</SPAN><BR /> DESTINATION<SPAN class="L0S33">'NONE'</SPAN><BR /> CALLING&nbsp;handle1&nbsp;<SPAN class="L0S52">ON&nbsp;</SPAN><SPAN class="L0S52">END&nbsp;</SPAN><SPAN class="L0S52">OF&nbsp;</SPAN><SPAN class="L0S52">TASK</SPAN><BR /> <SPAN class="L0S52">EXPORTING</SPAN><BR /> salesdocument&nbsp;<SPAN class="L0S55">=&nbsp;</SPAN>sdoc1<SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">CALL&nbsp;</SPAN><SPAN class="L0S52">FUNCTION&nbsp;</SPAN><SPAN class="L0S33">'BAPI_SALESORDER_GETSTATUS'</SPAN><BR /> <SPAN class="L0S52">STARTING&nbsp;</SPAN><SPAN class="L0S52">NEW&nbsp;</SPAN><SPAN class="L0S52">TASK&nbsp;</SPAN><SPAN class="L0S33">'FUNC2'</SPAN><BR /> DESTINATION&nbsp;<SPAN class="L0S33">'NONE'</SPAN><BR /> CALLING&nbsp;handle2&nbsp;<SPAN class="L0S52">ON&nbsp;</SPAN><SPAN class="L0S52">END&nbsp;</SPAN><SPAN class="L0S52">OF&nbsp;</SPAN><SPAN class="L0S52">TASK</SPAN><BR /> <SPAN class="L0S52">EXPORTING</SPAN><BR /> salesdocument&nbsp;<SPAN class="L0S55">=&nbsp;</SPAN>sdoc2<SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">WAIT&nbsp;</SPAN>UNTIL&nbsp;chk1&nbsp;<SPAN class="L0S55">=&nbsp;</SPAN>abap_true&nbsp;<SPAN class="L0S52">AND&nbsp;</SPAN>chk2&nbsp;<SPAN class="L0S55">=&nbsp;</SPAN>abap_true<SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">WRITE</SPAN><SPAN class="L0S55">:</SPAN>/<SPAN class="L0S33">'SUCCESS'</SPAN><SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">ENDMETHOD</SPAN><SPAN class="L0S55">.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class="L0S31">"call method</SPAN><BR /> <BR /> <SPAN class="L0S52">METHOD&nbsp;</SPAN>handle1<SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">DATA</SPAN><SPAN class="L0S55">:&nbsp;</SPAN>ret1&nbsp;<SPAN class="L0S52">TYPE&nbsp;</SPAN><SPAN class="L0S52">TABLE&nbsp;</SPAN><SPAN class="L0S52">OF&nbsp;</SPAN>bapisdstat<SPAN class="L0S55">.</SPAN><BR /> <SPAN class="L0S52">RECEIVE&nbsp;</SPAN>RESULTS&nbsp;<SPAN class="L0S52">FROM&nbsp;</SPAN><SPAN class="L0S52">FUNCTION&nbsp;</SPAN><SPAN class="L0S33">'BAPI_SALESORDER_GETSTATUS'</SPAN><BR /> <SPAN class="L0S52">TABLES</SPAN><BR /> statusinfo&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="L0S55">=&nbsp;</SPAN>ret1<SPAN class="L0S55">.</SPAN><BR /> ret11&nbsp;<SPAN class="L0S55">=&nbsp;</SPAN>ret1<SPAN class="L0S55">.</SPAN><BR /> chk1&nbsp;<SPAN class="L0S55">=&nbsp;</SPAN>abap_true<SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">ENDMETHOD</SPAN><SPAN class="L0S55">.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class="L0S31">"HANDLE1</SPAN><BR /> <BR /> <SPAN class="L0S52">METHOD&nbsp;</SPAN>handle2<SPAN class="L0S55">.</SPAN><BR /> <SPAN class="L0S52">DATA</SPAN><SPAN class="L0S55">:&nbsp;</SPAN>ret2&nbsp;<SPAN class="L0S52">TYPE&nbsp;</SPAN><SPAN class="L0S52">TABLE&nbsp;</SPAN><SPAN class="L0S52">OF&nbsp;</SPAN>bapisdstat<SPAN class="L0S55">.</SPAN><BR /> <SPAN class="L0S52">RECEIVE&nbsp;</SPAN>RESULTS&nbsp;<SPAN class="L0S52">FROM&nbsp;</SPAN><SPAN class="L0S52">FUNCTION&nbsp;</SPAN><SPAN class="L0S33">'BAPI_SALESORDER_GETSTATUS'</SPAN><BR /> <SPAN class="L0S52">TABLES</SPAN><BR /> statusinfo&nbsp;&nbsp;<SPAN class="L0S55">=&nbsp;</SPAN>ret2<SPAN class="L0S55">.</SPAN><BR /> ret22&nbsp;<SPAN class="L0S55">=&nbsp;</SPAN>ret2<SPAN class="L0S55">.</SPAN><BR /> chk1&nbsp;<SPAN class="L0S55">=&nbsp;</SPAN>abap_true<SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">ENDMETHOD</SPAN><SPAN class="L0S55">.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class="L0S31">"HANDLE2</SPAN><BR /> <BR /> <SPAN class="L0S52">ENDCLASS</SPAN><SPAN class="L0S55">.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class="L0S31">"LCL_DEMO&nbsp;&nbsp;IMPLEMENTATION</SPAN><BR /> <BR /> <SPAN class="L0S52">START-OF-SELECTION</SPAN><SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">PARAMETERS</SPAN><SPAN class="L0S55">:&nbsp;</SPAN>p_sdoc1&nbsp;<SPAN class="L0S52">TYPE&nbsp;</SPAN>bapivbeln<SPAN class="L0S70">-</SPAN>vbeln<SPAN class="L0S55">,</SPAN><BR /> p_sdoc2&nbsp;<SPAN class="L0S52">TYPE&nbsp;</SPAN>bapivbeln<SPAN class="L0S70">-</SPAN>vbeln<SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">CALL&nbsp;</SPAN><SPAN class="L0S52">METHOD&nbsp;</SPAN>lcl_demo<SPAN class="L0S70">=&gt;</SPAN><SPAN class="L0S52">call</SPAN><BR /> <SPAN class="L0S52">EXPORTING</SPAN><BR /> sdoc1&nbsp;<SPAN class="L0S55">=&nbsp;</SPAN>p_sdoc1<BR /> sdoc2&nbsp;<SPAN class="L0S55">=&nbsp;</SPAN>p_sdoc2<SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">LOOP&nbsp;</SPAN><SPAN class="L0S52">AT&nbsp;</SPAN>ret11&nbsp;<SPAN class="L0S52">INTO&nbsp;</SPAN>ret<SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">write</SPAN><SPAN class="L0S55">:&nbsp;</SPAN>/&nbsp;ret<SPAN class="L0S70">-</SPAN>doc_number&nbsp;<SPAN class="L0S55">,&nbsp;</SPAN>ret<SPAN class="L0S70">-</SPAN>material<SPAN class="L0S55">,&nbsp;</SPAN>ret<SPAN class="L0S70">-</SPAN>creation_date<SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">ENDLOOP</SPAN><SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">CLEAR&nbsp;</SPAN>ret<SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">LOOP&nbsp;</SPAN><SPAN class="L0S52">AT&nbsp;</SPAN>ret22&nbsp;<SPAN class="L0S52">INTO&nbsp;</SPAN>ret<SPAN class="L0S55">.</SPAN><BR /> <SPAN class="L0S52">write</SPAN><SPAN class="L0S55">:</SPAN>/&nbsp;ret<SPAN class="L0S70">-</SPAN>doc_number<SPAN class="L0S55">,</SPAN>ret<SPAN class="L0S70">-</SPAN>material<SPAN class="L0S55">,&nbsp;</SPAN>ret<SPAN class="L0S70">-</SPAN>creation_date<SPAN class="L0S55">.</SPAN><BR /> <BR /> <SPAN class="L0S52">ENDLOOP</SPAN><SPAN class="L0S55">.</SPAN><BR /> <BR /> &nbsp;<BR /> <BR /> <STRONG>PROGRAM:</STRONG><BR /> <P style="overflow: hidden;margin-bottom: 0px;text-align: center"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/SC1.png" /><STRONG>Image 1</STRONG></P><BR /> <STRONG>Defining a Class</STRONG> : When you define a class, you define a blueprint for a data type. This doesn't actually define any data, but it does define what the class name means, what an object of the class will consist of, and what operations can be performed on such an object.<BR /> <BR /> That is, it defines the abstract characteristics of an object, such as attributes, fields, and properties.<BR /> <BR /> <STRONG>Implementation</STRONG> : Implementation of a class contains the implementation of all its methods. In ABAP Objects, the structure of a class contains components such as attributes, methods, events, types, and constants.<BR /> <P style="overflow: hidden;margin-bottom: 0px;text-align: center"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/SC2.png" /><STRONG>Image 2</STRONG></P><BR /> <BR /> <UL class="ul"><BR /> <LI class="li"><BR /> <P class="p">ABAP keyword<STRONG><SPAN style="color: #000000"> CALL FUNCTION</SPAN></STRONG> &lt;function&gt; <STRONG>STARTING NEW TASK</STRONG> &lt;taskname&gt; with the <STRONG>DESTINATION IN GROUP </STRONG>argument.</P><BR /> </LI><BR /> <LI class="li"><BR /> <P class="p">Use this keyword to have the SAP system execute the function module call in parallel. Typically, you'll place this keyword in a loop in which you divide up the data that is to be processed into work packets. You can pass the data that is to be processed in the form of an internal table (EXPORT, TABLE arguments). The keyword implements parallel processing by dispatching asynchronous RFC calls to the servers that are available in the RFC server group specified for the processing.</P><BR /> </LI><BR /> </UL><BR /> <STRONG><SPAN class="ph emphasis emphasis">Waiting for job completion:</SPAN></STRONG>&nbsp; As Line No 37 : indicates wait until with abap boolean .<BR /> <BR /> As part of your task management, your job must wait until all of the parallel processing tasks have been completed.<BR /> <BR /> To do this, the program uses the <STRONG>WAIT UNTIL</STRONG> keyword to wait until the number of completed parallel processing tasks is equal to the number of tasks that were created.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/SC3.png" /></P><BR /> <P style="text-align: center"><STRONG>Image 3</STRONG></P><BR /> <STRONG>Methods</STRONG> : The definition of a method is declared in the class declaration and implemented in the implementation part of a class.<BR /> <BR /> The<STRONG> METHOD</STRONG> and <STRONG>ENDMETHOD</STRONG> statements are used to define the implementation part of a method.<BR /> <P class="p"><STRONG>ABAP </STRONG>keyword <STRONG>RECEIVE:</STRONG>&nbsp; Required if you wish to receive the results of the processing of an asynchronous RFC.</P><BR /> <P class="p"><STRONG> RECEIVE</STRONG> retrieves <STRONG>IMPORT</STRONG> and <STRONG>TABLE</STRONG> parameters as well as messages and return codes.</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/SC4.png" /></P><BR /> <P style="text-align: center"><STRONG>Image 4</STRONG></P><BR /> Image 4 : as its business implemented , declaring the parameter .CALL the method with respective parameter<BR /> <BR /> Use LOOP and ENDLOOP &nbsp;<B>executes the statement block between LOOP and ENDLOOP once for each read row</B>. The output response result determines how and to where the row contents are read. The table key with which the loop is executed can be determined in cond.<BR /> <BR /> &nbsp;<BR /> <BR /> <STRONG>OUTPUT:</STRONG><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/sc5.png" /></P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/SC6.png" /></P><BR /> Parallel processing is a method in computing of running two or more processors (CPUs)&nbsp;<B>to handle separate parts of an overall task</B>. Breaking up different parts of a task among multiple processors will help reduce the amount of time to run a program using class and methods, which helps in performance.<BR /> <BR /> Time consumption in OAbap is less compared to normal Abap reports.<BR /> <BR /> &nbsp;<BR /> <BR /> I hope Abapers will understand Parallel Processing with Classes and Methods.<BR /> <BR /> Please provide your feedback and your thoughts into comment section below.<BR /> <BR /> Do you have any Q&amp;A please reach to <A href="https://answers.sap.com/index.html" target="_blank" rel="noopener noreferrer">https://answers.sap.com/index.html&nbsp;</A>and post your<BR /> <BR /> questions.<BR /> <BR /> follow the ABAP Development environment Topic page&nbsp; <A href="https://community.sap.com/topics/abap" target="_blank">https://community.sap.com/topics/abap </A><BR /> <BR /> and for reading further blog post visit <A href="https://blogs.sap.com" target="_blank" rel="noopener noreferrer">https://blogs.sap.com&nbsp; </A><BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <BR /> Regards,<BR /> <BR /> Shruthi S. 2023-04-27T18:03:43+02:00 https://community.sap.com/t5/technology-blogs-by-members/principal-propagation-in-a-multi-cloud-solution-between-microsoft-azure-and/ba-p/13561150 Principal propagation in a multi-cloud solution between Microsoft Azure and SAP, Part VII: Invoke RFCs and BAPIs with Kerberos delegation from Microsoft Power Platform 2023-06-19T13:52:16+02:00 MartinRaepple https://community.sap.com/t5/user/viewprofilepage/user-id/171519 <TABLE bgcolor="#e7f5ff"><BR /> <TBODY><BR /> <TR><BR /> <TD><BR /> <BR /> This blog post is the <I>seventh </I>part of a tutorial series. For a better understanding of the concepts and technologies, it is highly recommended that you read <A href="https://blogs.sap.com/2021/04/13/principal-propagation-in-a-multi-cloud-solution-between-microsoft-azure-and-sap-business-technology-platform-btp-part-iv-sso-with-a-power-virtual-agent-chatbot-and-on-premises-data-gateway/" target="_blank" rel="noopener noreferrer">part IV</A> first, and then come back here again. <A href="https://blogs.sap.com/2021/04/13/principal-propagation-in-a-multi-cloud-solution-between-microsoft-azure-and-sap-business-technology-platform-btp-part-iv-sso-with-a-power-virtual-agent-chatbot-and-on-premises-data-gateway/" target="_blank" rel="noopener noreferrer">Part IV</A> introduces the <A href="https://learn.microsoft.com/en-us/power-platform/" target="_blank" rel="nofollow noopener noreferrer">Microsoft Power Platform</A> with some of its key components that you will use in this part of the tutorial series as well, such as the <A href="https://learn.microsoft.com/en-us/data-integration/gateway/service-gateway-onprem-indepth" target="_blank" rel="nofollow noopener noreferrer">On-Premises Data Gateway (OPDG)</A>, <A href="https://docs.microsoft.com/en-us/power-automate/" target="_blank" rel="nofollow noopener noreferrer">Power Automate</A>, and <A href="https://flow.microsoft.com/en-us/connectors/" target="_blank" rel="nofollow noopener noreferrer">Connectors</A>.<BR /> <BR /> Since there is no "one-size-fits-all" approach for integration scenarios between Microsoft's and SAP's platforms using principal propagation, this series starts with <A href="https://blogs.sap.com/2020/07/17/principal-propagation-in-a-multi-cloud-solution-between-microsoft-azure-and-sap-cloud-platform-scp/" target="_blank" rel="noopener noreferrer">part I</A> explaining the technology standards for principal propagation in the context of calling a simple Web Service on SAP Business Technology Platform (BTP) on behalf of the authenticated user (or <EM>principal</EM>) from Azure Active Directory (Azure AD). Parts <A href="https://blogs.sap.com/2020/10/01/principal-propagation-in-a-multi-cloud-solution-between-microsoft-azure-and-sap-cloud-platform-scp-part-ii" target="_blank" rel="noopener noreferrer">II</A>, <A href="https://blogs.sap.com/2021/02/24/principal-propagation-in-a-multi-cloud-solution-between-microsoft-azure-and-sap-cloud-platform-scp-part-iii-teams-sso-process-integration-core-data-services/" target="_blank" rel="noopener noreferrer">III</A>, <A href="https://blogs.sap.com/2021/04/13/principal-propagation-in-a-multi-cloud-solution-between-microsoft-azure-and-sap-business-technology-platform-btp-part-iv-sso-with-a-power-virtual-agent-chatbot-and-on-premises-data-gateway" target="_blank" rel="noopener noreferrer">IV</A> and <A href="https://blogs.sap.com/2022/02/13/principal-propagation-in-a-multi-cloud-solution-between-microsoft-azure-and-sap-business-technology-platform-btp-part-v-production-readiness-with-unified-api-and-infrastructure-management/" target="_blank" rel="noopener noreferrer">V</A> extend this scenario step by step by adding on-premise connectivity, Microsoft Teams integration, and API management to it. I do recommend reading these parts as well to get an understanding of the different scenarios and recommended options to implement them. <A href="https://blogs.sap.com/2022/11/02/principal-propagation-in-a-multi-cloud-solution-between-microsoft-azure-and-sap-business-technology-platform-btp-part-vi-calling-the-microsoft-graph-on-behalf-of-the-sap-authenticated-user/" target="_blank" rel="noopener noreferrer">Part VI</A> looks at the reverse direction for propagating the principal from SAP Cloud Identity Services to Azure in the context of calling the Microsoft Graph API from an BTP application.<BR /> <BR /> This part takes in in-depth look at principal propagation for an application built with the <A href="https://learn.microsoft.com/en-us/power-platform/?WT.mc_id=webupdates_GEP_Powerplatformlearn-web-wwl" target="_blank" rel="nofollow noopener noreferrer">Microsoft Power Platform</A> making a <A href="https://help.sap.com/docs/ABAP_PLATFORM_NEW/753088fc00704d0a80e7fbd6803c8adb/4888068ad9134076e10000000a42189d.html" target="_blank" rel="noopener noreferrer">Remote Function Call (RFC)</A> to an SAP system on-premise using a <A href="https://help.sap.com/docs/ABAP_PLATFORM_NEW/166400f6be7b46e8adc6b90fd20f3516/485f9ba265c907dce10000000a42189d.html" target="_blank" rel="noopener noreferrer">Business Application Programming Interface (BAPI)</A> to search a product catalogue. Check out <A href="https://www.saponazurepodcast.de/episode142/" target="_blank" rel="nofollow noopener noreferrer">episode 142</A> of the <A href="https://www.saponazurepodcast.de" target="_blank" rel="nofollow noopener noreferrer">SAP on Azure video podcast series</A>&nbsp;for a live demo of this scenario.</TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> All variants for principal propagation in this blog series used HTTP secured by <A href="https://datatracker.ietf.org/doc/html/rfc5246" target="_blank" rel="nofollow noopener noreferrer">Transport Layer Security (TLS)</A> as the application layer protocol for calling a Web service on BTP (see <A href="https://blogs.sap.com/2020/07/17/principal-propagation-in-a-multi-cloud-solution-between-microsoft-azure-and-sap-cloud-platform-scp/" target="_blank" rel="noopener noreferrer">part I</A>), an OData service on SAP NetWeaver Gateway (see parts <A href="https://blogs.sap.com/2020/10/01/principal-propagation-in-a-multi-cloud-solution-between-microsoft-azure-and-sap-cloud-platform-scp-part-ii" target="_blank" rel="noopener noreferrer">II</A>, <A href="https://blogs.sap.com/2021/02/24/principal-propagation-in-a-multi-cloud-solution-between-microsoft-azure-and-sap-cloud-platform-scp-part-iii-teams-sso-process-integration-core-data-services/" target="_blank" rel="noopener noreferrer">III</A>, <A href="https://blogs.sap.com/2021/04/13/principal-propagation-in-a-multi-cloud-solution-between-microsoft-azure-and-sap-business-technology-platform-btp-part-iv-sso-with-a-power-virtual-agent-chatbot-and-on-premises-data-gateway" target="_blank" rel="noopener noreferrer">IV</A> and <A href="https://blogs.sap.com/2022/02/13/principal-propagation-in-a-multi-cloud-solution-between-microsoft-azure-and-sap-business-technology-platform-btp-part-v-production-readiness-with-unified-api-and-infrastructure-management/" target="_blank" rel="noopener noreferrer">V</A>), or the Graph API (see <A href="https://blogs.sap.com/2022/11/02/principal-propagation-in-a-multi-cloud-solution-between-microsoft-azure-and-sap-business-technology-platform-btp-part-vi-calling-the-microsoft-graph-on-behalf-of-the-sap-authenticated-user/" target="_blank" rel="noopener noreferrer">part VI</A>) to call Microsoft 365 services. The <A href="https://datatracker.ietf.org/doc/html/rfc6749" target="_blank" rel="nofollow noopener noreferrer">OAuth 2.0 Authorization Framework</A> is the de-facto security standard for restricting access to the data exposed by these <A href="https://en.wikipedia.org/wiki/Representational_state_transfer" target="_blank" rel="nofollow noopener noreferrer">RESTful services</A>. To enable principal propagation, additional standards such as the <A href="http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf" target="_blank" rel="nofollow noopener noreferrer">Security Assertion Markup Language (SAML) 2.0</A> and <A href="https://openid.net/specs/openid-connect-core-1_0.html" target="_blank" rel="nofollow noopener noreferrer">OpenID Connect (OIDC) 1.0</A> are required for a secure and interoperable transfer of the security context and identity information of the authenticated user (or <EM>principal</EM>) across system- and network boundaries. Please refer to the other parts of this blog series for a detailled explanation how OAuth, SAML and OpenID can be combined for secure principal propagation.<BR /> <BR /> For <A href="https://help.sap.com/docs/ABAP_PLATFORM_NEW/753088fc00704d0a80e7fbd6803c8adb/4888068ad9134076e10000000a42189d.html" target="_blank" rel="noopener noreferrer">RFCs</A> and <A href="https://help.sap.com/docs/ABAP_PLATFORM_NEW/166400f6be7b46e8adc6b90fd20f3516/485f9ba265c907dce10000000a42189d.html" target="_blank" rel="noopener noreferrer">BAPIs</A>, none of the beforementioned protocols can be used to secure the communication and propagate the principal between an external client and the SAP Application Server (AS) ABAP. For these services, <A href="https://help.sap.com/doc/PRODUCTION/saphelp_nw74/7.4.16/en-us/e6/56f466e99a11d1a5b00000e835363f/frameset.htm" target="_blank" rel="noopener noreferrer">Secure Network Communications (SNC)</A> can be applied to secure RFCs. SNC uses the standardized Generic Security Service Application Program Interface (<A href="https://datatracker.ietf.org/doc/html/rfc2743" target="_blank" rel="nofollow noopener noreferrer">GSS-API</A>) for integrating with a cryptographic library for encrypting the data traffic on the network level and supporting single sign-on (SSO) to an SAP system using X.509 client certificates or the <A href="https://www.ietf.org/rfc/rfc4120.txt" target="_blank" rel="nofollow noopener noreferrer">Kerberos protocol</A> as specified in <A href="https://www.ietf.org/rfc/rfc4120.txt" target="_blank" rel="nofollow noopener noreferrer">RFC 4120</A>.<BR /> <H2 id="toc-hId-962940254">Principal Propagation with Kerberos Delegation</H2><BR /> The Kerberos protocol, named after the three-headed guard dog of Hades from the Greek mythology, requires a trusted authority, the Key Distribution Center (KDC), to facilitate SSO between the client and a "kerberized" service or resource on a server. The protocol not only defines these three entities, but also three phases of their message exchange as illustrated in figure 1:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/figure1-4.jpg" height="330" width="400" /></P><BR /> Figure 1: <EM>The Kerberos protocol</EM><BR /> <OL><BR /> <LI><B>Authentication Service (AS) exchange: </B>The client requests a ticket-granting ticket (<CODE>TGT</CODE>) with an authentication service request (<CODE>AS_REQ</CODE>) message (1) from the Authentication Service (AS) of the KDC. The user authenticates at the AS by encrypting this message with her secret key K<SUB>C </SUB>that is created by hashing the user's password stored in the KDC's account directory. Upon successfull decryption, the KDC constructs the TGT for the user and returns it to the client with a <CODE>AS_REP</CODE> (2) message. The TGT is encrypted with the KDC's secret key K<SUB>K</SUB> and is a special type of Kerberos ticket that can only be used by the client to obtain other tickets from the KDC.</LI><BR /> <LI><B>Ticket-Granting Service (TGS) exchange: </B>To establish an authenticated communication session with the service, the client uses the TGT (instead of the long-term secret key K<SUB>C</SUB>&nbsp;from the user's hashed password) and requests a service ticket (ST) from the KDC's Ticket Granting Service (TGS) with a ticket-granting service request (<CODE>TGS_REQ</CODE>) message (3). The service for which the ST is requested for is identified by its <EM>Service Principal Name (SPN)</EM>. SPNs uniquely identify an instance of a service and are registered on a user or computer account in the KDCs account directory by setting the <CODE>servicePrincipalName</CODE> attribute of the object. The KDC returns the ST for the service encrypted with the service key K<SUB>S</SUB> to the client with a ticket-granting service response (<CODE>TGS_REP</CODE>) message (4).</LI><BR /> <LI><B>Client/Server Authentication (AP) exchange: </B>The client sends the ST to the service with an application server request (<CODE>AP_REQ</CODE>) message requesting access to the service (5). The server can validate the ticket by decrypting it with its service key K<SUB>S</SUB> where it finds the user's unique name (cname). Optionally, the client might request that the server verify its own identity by sending back a application server response (<CODE>AP_REP</CODE>) message (6).</LI><BR /> </OL><BR /> For propagating the authenticated user from the service to another service, the Kerberos protocol provides the <A href="https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/3bff5864-8135-400e-bdd9-33b552051d94" target="_blank" rel="nofollow noopener noreferrer">Service for User (S4U) extensions</A>. These extensions allow a service to obtain a Kerberos service ticket for a different service on-behalf-of a user that <EM>has not</EM> authenticated to the KDC. S4U includes the <EM>S4U2self</EM> and <EM>S4U2proxy</EM> extensions:<BR /> <UL><BR /> <LI>The <A href="https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/02636893-7a1f-4357-af9a-b672e3e3de13" target="_blank" rel="nofollow noopener noreferrer">Service-for-User-to-Self</A> (<EM>S4U2self</EM>) extension is intended to be used by a service to obtain a ticket <EM>for itself</EM> on-behalf-of a user who has authenticated in some other way than by using Kerberos to the service. With S4U2self<EM>,</EM> the service gets a ticket just as if the user had used Kerberos.</LI><BR /> <LI>The <A href="https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/bde93b0e-f3c9-4ddf-9f44-e1453be7af5a" target="_blank" rel="nofollow noopener noreferrer">Service-for-User-to-Proxy</A> (<EM>S4U2proxy</EM>) extension allows a service to<BR /> call another service, acting on-behalf-of the user. The first service uses a Kerberos service ticket as if the user had obtained the service ticket for it and sends the ticket to a second service directly. Configuration at the KDC's TGS can be used to limit the scope of the S4U2proxy extension, also known as <EM style="font-size: 1rem">constrained</EM><SPAN style="font-size: 1rem"> delegation. The second service is typically a proxy performing some work for the first service, and the proxy requires to do that work under the authorization context of the user. </SPAN></LI><BR /> </UL><BR /> Figure 2 shows the two S4U Kerberos extensions (steps 10 to 13) in the context of the complete end-to-end message flow for the scenario in this blog post:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/scenario_overview-3.png" /></P><BR /> Figure 2: <EM>System landscape and message flow</EM><BR /> <OL><BR /> <LI>Jack Davis as the application test user in this tutorial logs on to the domain-joined Windows workstation on the corporate network. This results in a Kerberos TGT issued by the local Active Directory Domain Service (AD DS) acting as the KDC (see figure 1, steps 1 &amp; 2). The same applies to services in the corporate domain, such as the OPDG, that also obtains a TGT from AD DS.</LI><BR /> <LI>The user launches the "SAP Product Search" Power Platform app in a web browser. The app consists of two components (see figure 3): A <A href="https://learn.microsoft.com/en-us/power-apps/" target="_blank" rel="nofollow noopener noreferrer">canvas app</A> providing the user interface to search for the price of a product in the Enterprise Procurement Model (EPM) demo application of the SAP system in the corporate network. The business logic to connect to SAP, transforming the BAPI response data, and error handling, is implemented in a <A href="https://learn.microsoft.com/en-us/power-automate/" target="_blank" rel="nofollow noopener noreferrer">Power Automate flow</A>. The flow uses the <A href="https://learn.microsoft.com/en-us/connectors/saperp/" target="_blank" rel="nofollow noopener noreferrer">SAP ERP Connector</A>'s prebuilt <EM><A href="https://learn.microsoft.com/en-us/connectors/saperp/#call-sap-function-(v2)" target="_blank" rel="nofollow noopener noreferrer">Call SAP function (V2)</A></EM> action to invoke the <CODE>BAPI_EPM_PRODUCT_GET_DETAIL</CODE> <A href="https://help.sap.com/docs/SAP_NETWEAVER_750/166400f6be7b46e8adc6b90fd20f3516/485f9ba265c907dce10000000a42189d.html" target="_blank" rel="noopener noreferrer">Business Application Programming Interface (BAPI)</A> of the EPM demo application.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/figure2-1-1.jpg" height="241" width="470" />Figure 3: <EM>Application components&nbsp;</EM></LI><BR /> <LI>For <A href="https://learn.microsoft.com/en-us/power-platform/admin/security/authenticate-services" target="_blank" rel="nofollow noopener noreferrer">authentication to Power Platform</A>, the app requires an OpenID Connect (ID) token for authentication and an OAuth access token for authorization, and redirects the user to the app's Azure AD tenant authorization endpoint to trigger authentication with the <A href="https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow" target="_blank" rel="nofollow noopener noreferrer">OAuth 2.0 authorization code flow</A>. For a complete SSO experience, the setup in this scenario synchronizes the user accounts from the corporate Active Directory Domain Services (AD DS) to the Azure AD tenant with <A href="https://learn.microsoft.com/en-us/azure/active-directory/hybrid/connect/whatis-azure-ad-connect" target="_blank" rel="nofollow noopener noreferrer">Azure AD Connect</A> and <EM>Password Hash Synchronization</EM> (PHS) enabled. With PHS, hashes of the user passwords in AD DS are synchronized by Azure AD Connect to Azure AD so that the users can login with the same password on-premises and in the cloud. This feature can be combined with <A href="https://learn.microsoft.com/en-us/azure/active-directory/hybrid/connect/how-to-connect-sso-how-it-works" target="_blank" rel="nofollow noopener noreferrer"><EM>Seamless SSO</EM></A> in Azure AD Connect to automatically sign-in users when they are on their corporate devices connected to the corporate network. The following steps 4 to 6 explain this process in more detail.</LI><BR /> <LI>Azure AD challenges the browser to provide a Kerberos ticket for the user by sending an <CODE>HTTP 401 Unauthorized</CODE> response.</LI><BR /> <LI>The browser requests the Kerberos ticket from AD DS for the computer account representing Azure AD in AD DS.</LI><BR /> <LI>The browser forwards the encrypted Kerberos ticket to Azure AD which can decrypt it using the shared key for the account.</LI><BR /> <LI>Upon successful SSO to the cloud, the Azure AD tenant generates an OAuth 2.0 authorization code for the user and sends it to the SAP Product Search app by redirecting the user's web browser.</LI><BR /> <LI>The app redeems the authorization code for an OAuth access token and OpenID Connect (ID) token by sending the authorization code to the Azure AD tenant's token endpoint.</LI><BR /> <LI>When the user enters a product ID and clicks the search button, the app triggers the flow which in turn uses the SAP ERP connector to call the SAP system's BAPI via the OPDG on the corporate network. The flow passes the product ID to the BAPI's input parameters and sends the user's ID token in the call to the SAP ERP Connector.&nbsp;The ID token must successfully pass the validations of its <A href="https://learn.microsoft.com/en-us/azure/active-directory/develop/id-token-claims-reference#payload-claims" target="_blank" rel="nofollow noopener noreferrer">claims</A>, such as the intended recipient (<CODE>aud</CODE>ience), the trusted <CODE>iss</CODE>uer who constructed the token (Azure AD tenant), and the validity of the <CODE>exp</CODE>iration of the token, before the User Principal Name (UPN) is extracted from it and send to the OPDG.</LI><BR /> <LI>OPDG uses the Kerberos <A href="https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/02636893-7a1f-4357-af9a-b672e3e3de13" target="_blank" rel="nofollow noopener noreferrer">S4U2self</A> extension to retrieve a <A href="https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/4a624fb5-a078-4d30-8ad1-e9ab71e0bc47#gt_4c6cd79b-120d-4ee1-ab24-d1b000e0b3ca" target="_blank" rel="nofollow noopener noreferrer">forwardable</A> service ticket for itself on behalf of the Azure AD-authenticated user. To do so, OPDG has to run under a service user account (e.g. CORP\GatewaySvc) within the AD domain, uniquely identified by its SPN (e.g. <EM>gateway/WIN-OPDG</EM>). OPDG needs to map the UPN from the Azure AD-authenticated user to a different UPN of the user in the on-premise AD, using an unused Active Directory attribute such as <CODE>msDS-cloudExtensionAttribute1</CODE> in this scenario. This lab setup requires user mapping because the user's UPN suffix in Azure AD (e.g. jdavis@<EM>bestruncorp.onmicrosoft.com</EM>) is different from her suffix in the corporate AD (e.g. jdavis@<EM>corp.bestrun.com</EM>). As specified by the <A style="font-size: 1rem" href="https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/02636893-7a1f-4357-af9a-b672e3e3de13" target="_blank" rel="nofollow noopener noreferrer">S4U2self</A> extension,&nbsp;OPDG creates the <A href="https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/aceb70de-40f0-4409-87fa-df00ca145f5a" target="_blank" rel="nofollow noopener noreferrer">PA_FOR_USER</A> data structure with the mapped user name and sends it with a <CODE>TGS_REQ</CODE> message to AD DS.</LI><BR /> <LI>AD DS uses OPDG's identity from its <CODE>TGT</CODE> sent with the <CODE>TGS_REQ</CODE> message to create the OPDG service ticket and returns the service ticket for the user in the <CODE>TGS_REP</CODE> message.</LI><BR /> <LI>The SAP system is configured for SNC and Kerberos-based SSO (e.g. for SAP GUI), which requires registration of an SPN for the SAP system's service account in AD DS following the format "SAP/&lt;SID&gt;", e.g. SAP/A4H. OPDG is now attempting to obtain a service ticket for the SAP system on-behalf-of the user with the <A href="https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/bde93b0e-f3c9-4ddf-9f44-e1453be7af5a" target="_blank" rel="nofollow noopener noreferrer">S4U2proxy</A> Kerberos extension. OPDG sends the <CODE>TGS_REQ</CODE> message with the user's service ticket for OPDG obtained in the previous step as an <CODE>additional-ticket</CODE> in the request.</LI><BR /> <LI>AD DS&nbsp;makes sure the <CODE>forwardable</CODE> flag is set in the OPDG's service ticket found in the&nbsp; <CODE>additional-ticket</CODE> and uses its local policy to determine if OPDG is allowed to obtain a service ticket on behalf of a user to the SAP system. If these conditions are met, the TGS crafts the <CODE>TGS_REP</CODE> message to return the user's service ticket to the SAP. This response contains the <CODE>cname</CODE> field identifying the user's UPN in AD DS that was taken from the <CODE>additional-ticket</CODE>.</LI><BR /> <LI>OPDG utilizes the locally installed <A href="https://support.sap.com/en/product/connectors/msnet.html" data-linktype="external" target="_blank" rel="noopener noreferrer">SAP Connector for Microsoft .NET 3.1 (NCo 3.1)</A> and SAP Cryptographic Library to make a secure, SNC-protected synchronous RFC call to the BAPI, authenticated with the Kerberos ticket from the previous step for the SAP system obtained on-behalf-of the Azure AD-authenticated user from AD DS. The SAP system can single sign-on the user with the Kerberos ticket by mapping its <CODE>cname</CODE> to the user's SNC name (e.g. p:CN=JDAVIS@CORP.BESTRUN.COM).</LI><BR /> <LI>If all authorization checks for the propagated user are successfull (such as the permission to call the BAPI), the response from the BAPI is sent back by the SAP ERP Connector to the flow, checked for any errors, and parsed for the price of the product which is returned to the app.</LI><BR /> </OL><BR /> <H3 id="toc-hId-895509468">Prerequisites and lab setup</H3><BR /> The following list of prerequisites must be met to successfully complete the exercises of part VII:<BR /> <UL><BR /> <LI>A Power Platform environment. You can reuse the environment from <A href="https://blogs.sap.com/2021/04/13/principal-propagation-in-a-multi-cloud-solution-between-microsoft-azure-and-sap-business-technology-platform-btp-part-iv-sso-with-a-power-virtual-agent-chatbot-and-on-premises-data-gateway/" target="_blank" rel="noopener noreferrer">part IV</A>, or (if you started your journey here) can get a new one with a <A href="https://powerapps.microsoft.com/en-us/" target="_blank" rel="nofollow noopener noreferrer">free Power Apps trial account</A> or <A href="https://developer.microsoft.com/en-us/microsoft-365/dev-program" target="_blank" rel="nofollow noopener noreferrer">Microsoft 365 Developer license</A> and by following <A href="https://learn.microsoft.com/en-us/power-platform/admin/create-environment#create-an-environment-without-a-database" target="_blank" rel="nofollow noopener noreferrer">these instructions</A>.</LI><BR /> <LI>Administrative access to an Active Directory domain and on-premises systems for simulating the corporate network in your lab environment. You can create the required systems in your lab environment as Hyper-V VMs and configure them according to the table below:<BR /> <TABLE style="border-collapse: collapse;width: 100%;height: 319px" border="1"><BR /> <TBODY><BR /> <TR style="height: 14px"><BR /> <TD style="width: 25.1282%;height: 14px"><STRONG>System</STRONG></TD><BR /> <TD style="width: 67.2109%;height: 14px"><STRONG>Operating system &amp; software</STRONG></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 25.1282%;height: 14px">Active Directory Domain Controller (AD DC)</TD><BR /> <TD style="width: 67.2109%;height: 14px"><BR /> <UL><BR /> <LI>Windows Server 2019</LI><BR /> <LI>Active Directory Domain Services (AD DS role). Installing the AD DS role and promoting a Windows Server to a domain controller is documented <A href="https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/deploy/install-a-new-windows-server-2012-active-directory-forest--level-200-" target="_blank" rel="nofollow noopener noreferrer">here</A>. The domain name used in this tutorial is <EM>corp.bestrun.com (NetBIOS: CORP), </EM>but you can also choose any other name.</LI><BR /> <LI><A href="https://go.microsoft.com/fwlink/?LinkId=615771" target="_blank" rel="nofollow noopener noreferrer">Azure AD Connect</A>, version 2.1.20.0, following <A href="https://learn.microsoft.com/en-us/azure/active-directory/hybrid/connect/how-to-connect-install-express" target="_blank" rel="nofollow noopener noreferrer">these installation instructions</A>.</LI><BR /> </UL><BR /> </TD><BR /> </TR><BR /> <TR style="height: 140px"><BR /> <TD style="width: 25.1282%;height: 140px">On-Premises Data Gateway (OPDG) Server</TD><BR /> <TD style="width: 67.2109%;height: 140px"><BR /> <UL><BR /> <LI>Windows Server 2019, domain-joined</LI><BR /> <LI><A href="https://www.microsoft.com/en-us/download/details.aspx?id=53127" target="_blank" rel="nofollow noopener noreferrer">On-Premises Data Gateway</A>, minimum <EM>version 3000.178.9 (June 2023) or newer</EM>. Installation instructions and how to register the OPDG in your Power Platform environment can be found <A href="https://learn.microsoft.com/en-us/data-integration/gateway/service-gateway-install" target="_blank" rel="nofollow noopener noreferrer">here</A>.</LI><BR /> <LI><A href="https://support.sap.com/en/product/connectors/msnet.html" data-linktype="external" target="_blank" rel="noopener noreferrer">SAP Connector for Microsoft .NET 3.1 (NCo 3.1)</A>. Select <EM>NCo 3.1 compiled with .NET Framework 4.6.2 - SAP Connector for Microsoft .NET 3.1.&lt;n&gt;.&lt;n&gt; for Windows 64 bit (x64) </EM>for download.</LI><BR /> <LI>SAP Cryptographic Library (<CODE>sapcrypto.dll</CODE>) 64 bit, version 8.5.25 (or newer).&nbsp;Download the latest version of the SAP Cryptographic Library from the <A href="https://support.sap.com/en/my-support/software-downloads.html" target="_blank" rel="noopener noreferrer">SAP Support Portal's Software Download</A> (S-User required). Search for "<KBD class="ph userinput">CommonCryptoLib"</KBD>&nbsp;in the&nbsp;<SPAN class="ph uicontrol">Support Packages and Patches</SPAN> area.</LI><BR /> <LI>Optional tools for troubleshooting:<BR /> <UL><BR /> <LI><A href="https://www.wireshark.org/download.html" target="_blank" rel="nofollow noopener noreferrer">Wireshark</A></LI><BR /> </UL><BR /> </LI><BR /> </UL><BR /> </TD><BR /> </TR><BR /> <TR style="height: 70px"><BR /> <TD style="width: 25.1282%;height: 70px">Workstation</TD><BR /> <TD style="width: 67.2109%;height: 70px"><BR /> <UL><BR /> <LI>Windows 10 Pro, domain-joined</LI><BR /> <LI>SAP GUI 7.70</LI><BR /> <LI>SAP Secure Login Client 3.0</LI><BR /> </UL><BR /> </TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 25.1282%">SAP System</TD><BR /> <TD style="width: 67.2109%"><BR /> <UL><BR /> <LI>SAP Application Server ABAP</LI><BR /> <LI><STRONG>Note</STRONG>: The SAP system <EM>is not required</EM> to be domain-joined and <EM>not to have</EM> line-of-sight to the AD DC. Therefore you can run it also in the cloud. If you don't have a system available for testing, the <A href="https://cal.sap.com/" target="_blank" rel="noopener noreferrer">SAP Cloud Appliance Library (CAL)</A> provides a simple way to deploy a test and development system for evaluation purposes on Azure. Use the <A href="https://cal.sap.com/catalog#/applianceTemplates/5a830213-f0cb-423e-ab5f-f7736e57f5a1" target="_blank" rel="noopener noreferrer">SAP ABAP Platform 1909, Developer Edition</A> appliance template which fulfills all requirements for this tutorial by installing an SAP Application Server ABAP 7.54 SP2.</LI><BR /> </UL><BR /> </TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> Table 1: <EM>Lab setup</EM></LI><BR /> <LI>Administrative access to an Azure AD tenant (which is included in the <A href="https://developer.microsoft.com/en-us/microsoft-365/dev-program" target="_blank" rel="nofollow noopener noreferrer">Microsoft 365 Developer license</A>). The domain name of the tenant used in this tutorial is <EM>bestruncorp.onmicrosoft.com, </EM>but you can also choose any other name.</LI><BR /> <LI>Checkout branch <CODE>part7</CODE> of the blog series <A href="https://github.com/raepple/azure-scp-principal-propagation/tree/part7" target="_blank" rel="nofollow noopener noreferrer">GitHub repository</A> with a Git client of your choice and the following commands:<BR /> <PRE class="language-php"><CODE>git clone <A href="https://github.com/raepple/azure-scp-principal-propagation.git" target="test_blank" rel="nofollow noopener noreferrer">https://github.com/raepple/azure-scp-principal-propagation.git</A><BR /> cd azure-scp-principal-propagation<BR /> git checkout part7</CODE></PRE><BR /> </LI><BR /> </UL><BR /> The following exercises require switching between different roles. The table below lists those user roles and corresponding accounts used in the configuration steps of the scenario:<BR /> <TABLE style="border-collapse: collapse;width: 100%" border="1"><BR /> <TBODY><BR /> <TR style="height: 14px"><BR /> <TD style="width: 30.8%;height: 14px"><STRONG>Role</STRONG></TD><BR /> <TD style="width: 69.2%;height: 14px"><STRONG>User accounts</STRONG></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 30.8%;height: 14px">Administrator</TD><BR /> <TD style="width: 69.2%;height: 14px"><BR /> <UL><BR /> <LI>SAP login: SAPADMIN</LI><BR /> <LI>AD login: CORP\Administrator</LI><BR /> <LI>Azure AD login: admin@bestruncorp.onmicrosoft.com</LI><BR /> <LI>SAP operating system login: &lt;SID&gt;adm</LI><BR /> </UL><BR /> </TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 30.8%">Developer</TD><BR /> <TD style="width: 69.2%"><BR /> <UL><BR /> <LI>SAP login: DEVUSER</LI><BR /> <LI>AD login: CORP\devuser</LI><BR /> <LI>Azure AD / Power Platform login: devuser@bestruncorp.onmicrosoft.com</LI><BR /> </UL><BR /> </TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 30.8%;height: 14px">Application test user</TD><BR /> <TD style="width: 69.2%;height: 14px"><BR /> <UL><BR /> <LI>SAP login: JDAVIS</LI><BR /> <LI>AD login: CORP\jdavis</LI><BR /> <LI>Azure AD login: jdavis@bestruncorp.onmicrosoft.com</LI><BR /> </UL><BR /> </TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> You will start the exercises to setup the end-to-end scenario illustrated in figure 2 by configuring the service account and SPN in the corporate Active Directory for the SAP system and setup the SAP system for SNC to test single sign-on with the SAP GUI. You can skip the following section if your SAP system is already configured for Kerberos-based SSO.<BR /> <H3 id="toc-hId-698995963">Configure SAP for Kerberos-based SSO with Active Directory</H3><BR /> <TABLE style="border-collapse: collapse;width: 100%"><BR /> <TBODY><BR /> <TR style="height: 32px"><BR /> <TD style="width: 8.83053%;height: 32px"><STRONG>Step</STRONG></TD><BR /> <TD style="width: 67.6953%;height: 32px"><STRONG>Description</STRONG></TD><BR /> <TD style="width: 23.4741%;height: 32px"><STRONG>Screenshot</STRONG></TD><BR /> </TR><BR /> <TR style="height: 32px"><BR /> <TD style="width: 8.83053%;height: 32px">1</TD><BR /> <TD style="width: 67.6953%;height: 32px"><BR /> <BR /> As a domain administrator, launch the&nbsp;<STRONG>Active Directory Users and Computers</STRONG> Microsoft Management Console (MMC) snap-in on the Domain Controller host.<BR /> <BR /> <STRONG>Right-click</STRONG> on <STRONG>Users</STRONG> in your domain to open the context menu and select <STRONG>New → User </STRONG>to create the new service account for the SAP system.</TD><BR /> <TD style="width: 23.4741%;height: 32px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-1-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 134px"><BR /> <TD style="width: 8.83053%;height: 134px">2</TD><BR /> <TD style="width: 67.6953%;height: 134px"><BR /> <BR /> Enter <STRONG>Kerberos&lt;SID&gt;</STRONG> as the <STRONG>First name</STRONG>, <STRONG>Full name</STRONG> and <STRONG>User login name</STRONG>.<BR /> <BR /> Replace &lt;SID&gt; with the ID of your SAP system (e.g. "A4H").<BR /> <BR /> Click <STRONG>Next</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 134px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-2-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 134px"><BR /> <TD style="width: 8.83053%;height: 134px">3</TD><BR /> <TD style="width: 67.6953%;height: 134px"><BR /> <BR /> Enter the password for the new service user account. Select <STRONG>User cannot change password</STRONG> and <STRONG>Password never expires</STRONG>.<BR /> <BR /> Click <STRONG>Next</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 134px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-3-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 133px"><BR /> <TD style="width: 8.83053%;height: 133px">4</TD><BR /> <TD style="width: 67.6953%;height: 133px">Click <STRONG>Finish</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 133px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-4-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 147px"><BR /> <TD style="width: 8.83053%;height: 147px">5</TD><BR /> <TD style="width: 67.6953%;height: 147px"><BR /> <BR /> Start the <STRONG>ADSI Editor</STRONG> (<STRONG>adsiedit.msc</STRONG>) to maintain the Service Principal Name (SPN) of the new service account.<BR /> <BR /> Select <STRONG>CN=Users</STRONG> from your domain's default naming context, and right-click on the <STRONG>CN=Kerberos&lt;SID&gt;</STRONG> user object.<BR /> <BR /> From the context menu, select <STRONG>Properties</STRONG>.<BR /> <BR /> Alternatively to steps 5 to 8, you can also use the command line as an Administrator and enter the following command:<BR /> <BR /> <CODE>setspn –A SAP/&lt;SID&gt; &lt;domain&gt;\Kerberos&lt;SID&gt;</CODE><BR /> <BR /> Replace &lt;domain&gt; with the NetBIOS name of your domain (e.g. "CORP"), and &lt;SID&gt; with the ID of your SAP system (e.g. "A4H").</TD><BR /> <TD style="width: 23.4741%;height: 147px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-5-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 165px"><BR /> <TD style="width: 8.83053%;height: 165px">6</TD><BR /> <TD style="width: 67.6953%;height: 165px"><BR /> <BR /> Select <STRONG>servicePrincipalName</STRONG> from the list.<BR /> <BR /> Click <STRONG>Edit</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 165px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-6-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 68px"><BR /> <TD style="width: 8.83053%;height: 68px">7</TD><BR /> <TD style="width: 67.6953%;height: 68px"><BR /> <BR /> Enter the <STRONG>Service Principal Name (SPN)</STRONG> for the SAP service account in the format "SAP/&lt;SID&gt;". Replace &lt;SID&gt; with the ID of your SAP system (e.g. "A4H").<BR /> <BR /> Click <STRONG>Add</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 68px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-7-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 176px"><BR /> <TD style="width: 8.83053%;height: 176px">8</TD><BR /> <TD style="width: 67.6953%;height: 176px">Click <STRONG>OK</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 176px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-8-1.jpg" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 8.83053%">9</TD><BR /> <TD style="width: 67.6953%"><BR /> <BR /> Go back to the <STRONG>Active Directory Users and Computers</STRONG> MMC snap-in and select the new SAP service account Kerberos&lt;SID&gt; from the <STRONG>Users</STRONG> list.<BR /> <BR /> <STRONG>Right-click</STRONG> on it and select <STRONG>Properties</STRONG> from the context menu.</TD><BR /> <TD style="width: 23.4741%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-8-1-1-1.jpg" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 8.83053%">10</TD><BR /> <TD style="width: 67.6953%"><BR /> <BR /> Switch to the <STRONG>Account</STRONG> tab.<BR /> <BR /> Under <STRONG>Account options</STRONG>, activate the checkbox for <STRONG>This account supports Kerberos AES 256 bit encryption</STRONG>.<BR /> <BR /> Click <STRONG>OK</STRONG>.</TD><BR /> <TD style="width: 23.4741%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-8-1-2.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 80px"><BR /> <TD style="width: 8.83053%;height: 80px">11</TD><BR /> <TD style="width: 67.6953%;height: 80px"><BR /> <BR /> <STRONG>Login</STRONG> to the domain on the workstation host with your application test user (e.g. CORP\jdavis).<BR /> <BR /> &nbsp;</TD><BR /> <TD style="width: 23.4741%;height: 80px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-8-1-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 98px"><BR /> <TD style="width: 8.83053%;height: 98px">12</TD><BR /> <TD style="width: 67.6953%;height: 98px"><BR /> <BR /> Start SAP GUI and login as the SAP administrator.<BR /> <BR /> Run transaction <STRONG>SNCWIZARD </STRONG>to start the SNC Configuration wizard.</TD><BR /> <TD style="width: 23.4741%;height: 98px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-9-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 115px"><BR /> <TD style="width: 8.83053%;height: 115px">13</TD><BR /> <TD style="width: 67.6953%;height: 115px"><BR /> <BR /> If you see the error message<BR /> <BR /> "DEFAULT profile in the DB and in the file system are different"<BR /> <BR /> then run transaction <STRONG>RZ10 </STRONG>first, and select <STRONG>Utilities → Import Profiles → Of active servers</STRONG>, and return to the SNCWIZARD.<BR /> <BR /> On the <STRONG>Start</STRONG> page of the SNC Configuration wizard, click <STRONG>Continue</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 115px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-10-2-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 118px"><BR /> <TD style="width: 8.83053%;height: 118px">14</TD><BR /> <TD style="width: 67.6953%;height: 118px">Accept the default value for system's SNC Identity and click <STRONG>Continue</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 118px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-11-1-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 117px"><BR /> <TD style="width: 8.83053%;height: 117px">15</TD><BR /> <TD style="width: 67.6953%;height: 117px">Click <STRONG>Continue</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 117px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-12-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 119px"><BR /> <TD style="width: 8.83053%;height: 119px">16</TD><BR /> <TD style="width: 67.6953%;height: 119px">Click <STRONG>Close</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 119px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-13-1-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 67px"><BR /> <TD style="width: 8.83053%;height: 67px">17</TD><BR /> <TD style="width: 67.6953%;height: 67px"><STRONG>Log off</STRONG> from the SAP system to restart the application server.</TD><BR /> <TD style="width: 23.4741%;height: 67px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-14.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 48px"><BR /> <TD style="width: 8.83053%;height: 48px">18</TD><BR /> <TD style="width: 67.6953%;height: 48px"><BR /> <BR /> As SAP system user &lt;SID&gt;adm, use the commands<BR /> <BR /> <CODE>sapcontrol -nr &lt;instance_number&gt; -function Stop</CODE><BR /> <BR /> and<BR /> <BR /> <CODE>sapcontrol -nr &lt;instance_number&gt; -function Start</CODE><BR /> <BR /> to restart the application server.<BR /> <BR /> Replace &lt;instance_number&gt; with the number of your application service instance, e.g. "00".</TD><BR /> <TD style="width: 23.4741%;height: 48px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/1-15-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 71px"><BR /> <TD style="width: 8.83053%;height: 71px">19</TD><BR /> <TD style="width: 67.6953%;height: 71px">After the restart of the application server, log on to SAP GUI and run transaction <STRONG>SNCWIZARD</STRONG> again.</TD><BR /> <TD style="width: 23.4741%;height: 71px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-16.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 120px"><BR /> <TD style="width: 8.83053%;height: 120px">20</TD><BR /> <TD style="width: 67.6953%;height: 120px">On the <STRONG>Start</STRONG> screen, click <STRONG>Continue</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 120px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-17-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 99px"><BR /> <TD style="width: 8.83053%;height: 99px">21</TD><BR /> <TD style="width: 67.6953%;height: 99px">Click <STRONG>Continue</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 99px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-18-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 30px"><BR /> <TD style="width: 8.83053%;height: 30px">22</TD><BR /> <TD style="width: 67.6953%;height: 30px">In the <STRONG>SPNEGO Configuration</STRONG>, click <STRONG>Display/Change</STRONG> to switch into edit mode.</TD><BR /> <TD style="width: 23.4741%;height: 30px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-19-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">23</TD><BR /> <TD style="width: 67.6953%;height: 14px">Click <STRONG>Add </STRONG>to configure a new Kerberos User Principal.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-21.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">24</TD><BR /> <TD style="width: 67.6953%;height: 14px"><BR /> <BR /> Enter the following values:<BR /> <BR /> <STRONG>User Principal Name</STRONG>: Kerberos&lt;SID&gt;@&lt;full-qualified name of your Active Directory Domain in uppercase letters, e.g. "CORP.BESTRUN.COM"&gt;<BR /> <BR /> <STRONG>Password</STRONG>: &lt;The password you specified in step 3&gt;<BR /> <BR /> <STRONG>Confirm Password</STRONG>: &lt;The password you specified in step 3&gt;</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-22.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">25</TD><BR /> <TD style="width: 67.6953%;height: 14px"><BR /> <BR /> Click <STRONG>Exit</STRONG>.<BR /> <BR /> Click <STRONG>Save</STRONG> to store the updated SPNEGO Configuration.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-23-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">26</TD><BR /> <TD style="width: 67.6953%;height: 14px">Click <STRONG>Skip</STRONG> on the X.509 Credentials wizard step.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-24-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">27</TD><BR /> <TD style="width: 67.6953%;height: 14px">Click <STRONG>Complete</STRONG> to finalize the wizard.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-25-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">28</TD><BR /> <TD style="width: 67.6953%;height: 14px"><BR /> <BR /> Open the SAP Secure Login Client and right-click on the <STRONG>Kerberos Token</STRONG> from the <STRONG>Profiles</STRONG> list.<BR /> <BR /> Select <STRONG>Copy SNC name to clipboard</STRONG>&nbsp;from the context menu.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-26-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">29</TD><BR /> <TD style="width: 67.6953%;height: 14px"><BR /> <BR /> Go back to SAP GUI and run transaction <STRONG>SU01 </STRONG>to maintain the application user's SNC mapping.<BR /> <BR /> Enter the application test user's ID (e.g. <STRONG>JDAVIS</STRONG>) in the <STRONG>User</STRONG> field and click <STRONG>Change</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-27-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">30</TD><BR /> <TD style="width: 67.6953%;height: 14px"><BR /> <BR /> Switch to the tab <STRONG>SNC</STRONG>.<BR /> <BR /> Maintain the user's <STRONG>SNC name</STRONG> by pasting the value you copied in step 28 from the clipboard (e.g. <STRONG>p:CN=JDAVIS@CORP.BESTRUN.COM</STRONG>).<BR /> <BR /> Click <STRONG>Save</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-30.jpg" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 8.83053%">31</TD><BR /> <TD style="width: 67.6953%"><BR /> <BR /> Repeat the last two steps for maintaining the SNC mapping for the developer's user account.<BR /> <BR /> Enter the developer user's ID (e.g. <STRONG>DEVUSER</STRONG>) in the <STRONG>User</STRONG> field and click <STRONG>Change</STRONG>.</TD><BR /> <TD style="width: 23.4741%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-29-1.jpg" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 8.83053%">32</TD><BR /> <TD style="width: 67.6953%"><BR /> <BR /> Switch to the tab <STRONG>SNC</STRONG>.<BR /> <BR /> Maintain the developer user's <STRONG>SNC name</STRONG> (e.g. <STRONG>p:CN=DEVUSER@CORP.BESTRUN.COM</STRONG>).<BR /> <BR /> Click <STRONG>Save</STRONG>.</TD><BR /> <TD style="width: 23.4741%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-29-2.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">33</TD><BR /> <TD style="width: 67.6953%;height: 14px"><STRONG>Log off</STRONG> as the administrator from SAP GUI.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-30-1-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 18px"><BR /> <TD style="width: 8.83053%;height: 18px">34</TD><BR /> <TD style="width: 67.6953%;height: 18px"><STRONG>Right-click</STRONG> on the SAP system connection and select <STRONG>Properties...</STRONG> from the menu.</TD><BR /> <TD style="width: 23.4741%;height: 18px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-30-1-1-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">35</TD><BR /> <TD style="width: 67.6953%;height: 14px"><BR /> <BR /> Switch to the <STRONG>Network</STRONG> tab.<BR /> <BR /> Activate the checkbox <STRONG>Activate Secure Network Communication</STRONG>.<BR /> <BR /> In the <STRONG>SNC Name</STRONG> field, enter the SAP system's SNC Identity from step 12.<BR /> <BR /> Click <STRONG>Finish</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-31.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">36</TD><BR /> <TD style="width: 67.6953%;height: 14px"><STRONG>Right-click</STRONG> on the system's connection and select <STRONG>SNC Logon with Single Sign-On</STRONG> to test the new SNC setup.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-32-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 128px"><BR /> <TD style="width: 8.83053%;height: 128px">37</TD><BR /> <TD style="width: 67.6953%;height: 128px"><BR /> <BR /> You should be single signed-on as user JDAVIS to the SAP system.<BR /> <BR /> Click <STRONG>Log off</STRONG> (or select <STRONG>System → Log off</STRONG> from the menu) to log out as user JDAVIS.</TD><BR /> <TD style="width: 23.4741%;height: 128px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-33.jpg" /></TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> <H3 id="toc-hId-502482458">Configure OPDG for Kerberos Constrained Delegation</H3><BR /> By default, OPDG runs as the machine-local service account <EM>NT Service\PBIEgwService</EM>. To use Kerberos Constrained Delegation with the protocol's S4U extensions, OPDG has to run under a service account in the domain.<BR /> <TABLE style="border-collapse: collapse;width: 100%"><BR /> <TBODY><BR /> <TR style="height: 32px"><BR /> <TD style="width: 8.83053%;height: 32px"><STRONG>Step</STRONG></TD><BR /> <TD style="width: 67.6953%;height: 32px"><STRONG>Description</STRONG></TD><BR /> <TD style="width: 23.4741%;height: 32px"><STRONG>Screenshot</STRONG></TD><BR /> </TR><BR /> <TR style="height: 32px"><BR /> <TD style="width: 8.83053%;height: 32px">38</TD><BR /> <TD style="width: 67.6953%;height: 32px"><BR /> <BR /> On the Domain Controller host, go back to the <STRONG>Active Directory Users and Computers</STRONG> Microsoft Management Console (MMC) snap-in.<BR /> <BR /> <STRONG>Right-click</STRONG> on <STRONG>Users</STRONG> in your domain and select <STRONG>New → User </STRONG>from the context menu.<BR /> <BR /> Enter "GatewaySvc<EM>"</EM> as the <STRONG>First name</STRONG>, <STRONG>Full name</STRONG> and <STRONG>User login name</STRONG>.<BR /> <BR /> Click <STRONG>Next</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 32px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-1-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 134px"><BR /> <TD style="width: 8.83053%;height: 134px">39</TD><BR /> <TD style="width: 67.6953%;height: 134px"><BR /> <BR /> Enter the password for the OPDG domain service account. Select <STRONG>User cannot change password</STRONG> and <STRONG>Password never expires</STRONG>.<BR /> <BR /> Click <STRONG>Next</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 134px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-3-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 135px"><BR /> <TD style="width: 8.83053%;height: 135px">40</TD><BR /> <TD style="width: 67.6953%;height: 135px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">Click <STRONG>Finish</STRONG>.</P><BR /> </TD><BR /> <TD style="width: 23.4741%;height: 135px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-3-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 155px"><BR /> <TD style="width: 8.83053%;height: 155px">41</TD><BR /> <TD style="width: 67.6953%;height: 155px"><BR /> <BR /> As the domain administrator, run the following command to create an SPN for the new service account which is required to configure the Kerberos delegation in the next step:<BR /> <BR /> <CODE>setspn –S gateway/&lt;OPDG hostname&gt; &lt;domain&gt;\GatewaySvc</CODE><BR /> <BR /> Replace &lt;OPDG hostname&gt; with the hostname of your OPDG system. You can find out the name by entering the command <CODE>hostname</CODE>.</TD><BR /> <TD style="width: 23.4741%;height: 155px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-12-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 132px"><BR /> <TD style="width: 8.83053%;height: 132px">42</TD><BR /> <TD style="width: 67.6953%;height: 132px"><BR /> <P style="overflow: hidden;margin-bottom: 0px"><STRONG>Right-click</STRONG> on the new service account and select <STRONG>Properties</STRONG> from the context menu.</P><BR /> </TD><BR /> <TD style="width: 23.4741%;height: 132px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-4-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 168px"><BR /> <TD style="width: 8.83053%;height: 168px">43</TD><BR /> <TD style="width: 67.6953%;height: 168px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">Switch to the <STRONG>Delegation</STRONG> tab.</P><BR /> Select <STRONG>Trust this user for delegation to specified services only</STRONG> and <STRONG>Use any authentication protocol</STRONG>.<BR /> <BR /> Click <STRONG>Add</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 168px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-5-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 28px"><BR /> <TD style="width: 8.83053%;height: 28px">44</TD><BR /> <TD style="width: 67.6953%;height: 28px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">Click <STRONG>Users or Computers</STRONG>.</P><BR /> </TD><BR /> <TD style="width: 23.4741%;height: 28px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-6-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 28px"><BR /> <TD style="width: 8.83053%;height: 28px">45</TD><BR /> <TD style="width: 67.6953%;height: 28px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">Enter "Kerberos&lt;SID&gt;" in the object names field. Replace &lt;SID&gt; with your SAP system's ID, e.g. "A4H".</P><BR /> <P style="overflow: hidden;margin-bottom: 0px">Click <STRONG>Check Names </STRONG>to resolve it to the full existent name.</P><BR /> <P style="overflow: hidden;margin-bottom: 0px">Click <STRONG>OK</STRONG>.</P><BR /> </TD><BR /> <TD style="width: 23.4741%;height: 28px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-7-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 28px"><BR /> <TD style="width: 8.83053%;height: 28px">46</TD><BR /> <TD style="width: 67.6953%;height: 28px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">The list of allowed services now contains the value from the SPN (Service Type / Computer) of the SAP system. The new OPDG service account can request a service ticket only for the SAP system on-behalf-of the propagated user with the Kerberos S4U2proxy protocol extension.</P><BR /> Click <STRONG>Select All</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 28px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-8-2.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 28px"><BR /> <TD style="width: 8.83053%;height: 28px">47</TD><BR /> <TD style="width: 67.6953%;height: 28px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">Click <STRONG>OK</STRONG>.</P><BR /> </TD><BR /> <TD style="width: 23.4741%;height: 28px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-9-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 199px"><BR /> <TD style="width: 8.83053%;height: 199px">48</TD><BR /> <TD style="width: 67.6953%;height: 199px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">Click <STRONG>OK.</STRONG></P><BR /> </TD><BR /> <TD style="width: 23.4741%;height: 199px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-10-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 98px"><BR /> <TD style="width: 8.83053%;height: 98px">49</TD><BR /> <TD style="width: 67.6953%;height: 98px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">The OPDG service account must be granted to local policies on the OPDG host.</P><BR /> Perform this configuration with the <STRONG>Local Group Policy Editor</STRONG> by running <STRONG>gpedit.msc</STRONG> from an Administrator command prompt.</TD><BR /> <TD style="width: 23.4741%;height: 98px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-11-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 142px"><BR /> <TD style="width: 8.83053%;height: 142px">50</TD><BR /> <TD style="width: 67.6953%;height: 142px">Go to&nbsp;<STRONG>Local Computer Policy</STRONG> →&nbsp;<STRONG>Computer Configuration</STRONG> →&nbsp;<STRONG>Windows Settings</STRONG> →&nbsp;<STRONG>Security Settings</STRONG> →&nbsp;<STRONG>Local Policies</STRONG> →&nbsp;<STRONG>User Rights Assignment</STRONG>.<BR /> <P style="overflow: hidden;margin-bottom: 0px">Grant the OPDG domain service account (e.g. "CORP\GatewaySvc") the local policy <STRONG>Act as part of the operating system</STRONG><STRONG>&nbsp;</STRONG>by double-clicking on it.</P><BR /> <P style="overflow: hidden;margin-bottom: 0px">Click <STRONG>Add User or Group</STRONG>.</P><BR /> </TD><BR /> <TD style="width: 23.4741%;height: 142px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-13-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 168px"><BR /> <TD style="width: 8.83053%;height: 168px">51</TD><BR /> <TD style="width: 67.6953%;height: 168px"><BR /> <BR /> Enter the name of your OPDG's domain service account (e.g. "GatewaySvc") and click <STRONG>Check Names</STRONG> to resolve it to the full existent name.<BR /> <BR /> Click <STRONG>OK</STRONG>.<BR /> <BR /> The service account's domain name (e.g. "CORP\GatewaySvc") is now added to the policy's user list.<BR /> <BR /> Click <STRONG>OK </STRONG>to apply the new configuration.</TD><BR /> <TD style="width: 23.4741%;height: 168px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-14-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">52</TD><BR /> <TD style="width: 67.6953%;height: 14px"><BR /> <BR /> Repeat the same step for the <STRONG>Impersonate a client after authentication </STRONG>policy by double-clicking on it.<BR /> <BR /> Click <STRONG>Add User or Group</STRONG> and resolve the OPDG's service account to the full existent name with <STRONG>Check Names</STRONG>.<BR /> <BR /> Click <STRONG>OK</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-15-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 28px"><BR /> <TD style="width: 8.83053%;height: 28px">53</TD><BR /> <TD style="width: 67.6953%;height: 28px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">The service account's name (e.g. "CORP\GatewaySvc") is now added to the policy's user list.</P><BR /> <P style="overflow: hidden;margin-bottom: 0px">Click <STRONG>OK</STRONG>.</P><BR /> <STRONG>Close</STRONG> the Local Group Policy Editor.</TD><BR /> <TD style="width: 23.4741%;height: 28px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-16-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 28px"><BR /> <TD style="width: 8.83053%;height: 28px">54</TD><BR /> <TD style="width: 67.6953%;height: 28px"><BR /> <BR /> Start the <STRONG>OPDG app </STRONG>from the desktop link on the gateway host, or by running <CODE>C:\Program Files\On-premises data gateway\EnterpriseGatewayConfigurator.exe</CODE>.<BR /> <BR /> Click <STRONG>Sign in</STRONG> to login as the Power Platform System administrator user who registered the OPDG in the environment.</TD><BR /> <TD style="width: 23.4741%;height: 28px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-17-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 28px"><BR /> <TD style="width: 8.83053%;height: 28px">55</TD><BR /> <TD style="width: 67.6953%;height: 28px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">Select <STRONG>Service Settings</STRONG> from the configurator's menu.</P><BR /> Click <STRONG>Change account</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 28px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-18.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 98px"><BR /> <TD style="width: 8.83053%;height: 98px">56</TD><BR /> <TD style="width: 67.6953%;height: 98px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">Click <STRONG>Apply and Restart</STRONG>.</P><BR /> </TD><BR /> <TD style="width: 23.4741%;height: 98px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-19.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 142px"><BR /> <TD style="width: 8.83053%;height: 142px">57</TD><BR /> <TD style="width: 67.6953%;height: 142px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">Enter your OPDG's service account name (e.g. "CORP\GatewaySvc") and password from step 34.</P><BR /> Click <STRONG>Configure</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 142px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-20.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 132px"><BR /> <TD style="width: 8.83053%;height: 132px">58</TD><BR /> <TD style="width: 67.6953%;height: 132px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">Provide your Power Platform System administrator sign-in account, by clicking on <STRONG>Sign in</STRONG>.</P><BR /> </TD><BR /> <TD style="width: 23.4741%;height: 132px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-21-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 143px"><BR /> <TD style="width: 8.83053%;height: 143px">59</TD><BR /> <TD style="width: 67.6953%;height: 143px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">Choose <STRONG>Migrate, restore or takeover an existing gateway </STRONG>to restore your gateway registration.</P><BR /> </TD><BR /> <TD style="width: 23.4741%;height: 143px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-22.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 140px"><BR /> <TD style="width: 8.83053%;height: 140px">60</TD><BR /> <TD style="width: 67.6953%;height: 140px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">Select your gateway cluster and instance from the drop-down boxes and provide the recovery key you've chosen during the initial registration.</P><BR /> Click <STRONG>Configure</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 140px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-23.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 76px"><BR /> <TD style="width: 8.83053%;height: 76px">61</TD><BR /> <TD style="width: 67.6953%;height: 76px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">After the restoration is complete, your OPDG service instance uses the domain service account (e.g. "CORP\GatewaySvc").</P><BR /> </TD><BR /> <TD style="width: 23.4741%;height: 76px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-24.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 28px"><BR /> <TD style="width: 8.83053%;height: 28px">62</TD><BR /> <TD style="width: 67.6953%;height: 28px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">Add the OPDG service account to the <STRONG>Windows Authorization and Access Group</STRONG>. This is requried because the user accounts that the gateway will impersonate are in Azure AD and thus not in the same domain as the OPDG service account.</P><BR /> On the Domain Controller host, go back to the <STRONG>Active Directory Users and Computers</STRONG> Microsoft Management Console (MMC) snap-in.<BR /> <BR /> Select the <STRONG>Builtin</STRONG> folder for your domain and <STRONG>double-click</STRONG> on the <STRONG>Windows Authorization and Access Group </STRONG>security group.<BR /> <BR /> &nbsp;</TD><BR /> <TD style="width: 23.4741%;height: 28px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-30-1-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 28px"><BR /> <TD style="width: 8.83053%;height: 28px">63</TD><BR /> <TD style="width: 67.6953%;height: 28px"><BR /> <BR /> Switch to the <STRONG>Members</STRONG> tab of the security group.<BR /> <BR /> Click <STRONG>Add</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 28px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-31-2.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 28px"><BR /> <TD style="width: 8.83053%;height: 28px">64</TD><BR /> <TD style="width: 67.6953%;height: 28px"><BR /> <BR /> Enter the name of your OPDG's domain service account (e.g. "GatewaySvc") and click <STRONG>Check Names</STRONG> to resolve it to the full existent SPN.<BR /> <BR /> Click <STRONG>OK</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 28px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-31-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 28px"><BR /> <TD style="width: 8.83053%;height: 28px">65</TD><BR /> <TD style="width: 67.6953%;height: 28px"><BR /> <BR /> The OPDG service account is now added to the policy's user list.<BR /> <BR /> Click <STRONG>OK </STRONG>to apply the new configuration.</TD><BR /> <TD style="width: 23.4741%;height: 28px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-32-1.jpg" /></TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> <H3 id="toc-hId-305968953">Install and configure the SAP Cryptographic Library</H3><BR /> For SNC communication between the OPDG and the SAP system, the SAP Cryptographic Library must be installed on the gateway host along with SAP <A href="https://support.sap.com/en/product/connectors/msnet.html" data-linktype="external" target="_blank" rel="noopener noreferrer">NCo 3.1</A>.<BR /> <TABLE style="border-collapse: collapse;width: 100%"><BR /> <TBODY><BR /> <TR style="height: 32px"><BR /> <TD style="width: 8.83053%;height: 32px"><STRONG>Step</STRONG></TD><BR /> <TD style="width: 67.6953%;height: 32px"><STRONG>Description</STRONG></TD><BR /> <TD style="width: 23.4741%;height: 32px"><STRONG>Screenshot</STRONG></TD><BR /> </TR><BR /> <TR style="height: 32px"><BR /> <TD style="width: 8.83053%;height: 32px">66</TD><BR /> <TD style="width: 67.6953%;height: 140px"><BR /> <BR /> Download the latest version of the <EM>SAP Cryptographic Library</EM> from the <A href="https://support.sap.com/en/my-support/software-downloads.html" target="_blank" rel="noopener noreferrer">SAP Support Portal's Software Download</A> (S-User required), and copy the library file (<CODE>sapcrypto.dll</CODE>) to the OPDG's installation directory on the gateway host (<CODE>C:\Program Files\On-premises data gateway</CODE>).<BR /> <BR /> <STRONG>Right-click</STRONG> on the <CODE>sapcrypto.dll</CODE> file and select <STRONG>Properties</STRONG> from the context menu.</TD><BR /> <TD style="width: 23.4741%;height: 140px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-26.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 193px"><BR /> <TD style="width: 8.83053%">67</TD><BR /> <TD style="width: 67.6953%;height: 193px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">Switch to the <STRONG>Details</STRONG> tab to check the version of the library. It should be 8.5.25 or newer.</P><BR /> Click <STRONG>OK</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 193px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-27.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 98px"><BR /> <TD style="width: 8.83053%">68</TD><BR /> <TD style="width: 67.6953%;height: 98px"><BR /> <P style="overflow: hidden;margin-bottom: 0px">Create a new text file <CODE>sapcrypto.ini</CODE> in the same directory (<CODE>C:\Program Files\On-premises data gateway</CODE>) with the following content:</P><BR /> <CODE>ccl/snc/enable_kerberos_in_client_role = 1</CODE><BR /> <BR /> <STRONG>Save</STRONG> the file.</TD><BR /> <TD style="width: 23.4741%;height: 98px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-28.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 28px"><BR /> <TD style="width: 8.83053%">69</TD><BR /> <TD style="width: 67.6953%;height: 28px"><BR /> <BR /> Grant <EM>read</EM>&nbsp;and&nbsp;<EM>execute</EM> permissions to both the <CODE>sapcrypto.ini</CODE>&nbsp;and&nbsp;<CODE>sapcrypto.dll</CODE> files to the gateway service user account and the AD user(s) that the service user impersonates.<BR /> <BR /> <STRONG>Right-click</STRONG> on the files and select <STRONG>Properties</STRONG> from the context menu. Switch to the <STRONG>Security</STRONG> tab.<BR /> <BR /> Check that the groups <STRONG>Domain Users</STRONG> and <STRONG>Authenticated Users</STRONG> are in the list.<BR /> <BR /> Click <STRONG>OK</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 28px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-29-1.jpg" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 8.83053%">70</TD><BR /> <TD style="width: 67.6953%"><BR /> <BR /> Create a&nbsp;<CODE>CCL_PROFILE</CODE> system environment variable and set its value to the path of the<CODE>sapcrypto.ini</CODE>configuration file.<BR /> <BR /> On the gateway host, launch the <STRONG>Control Panel</STRONG> and navigate to <STRONG>System and Security → System</STRONG>.<BR /> <BR /> Click <STRONG>Advanced system settings</STRONG>.</TD><BR /> <TD style="width: 23.4741%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/3-4-1.jpg" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 8.83053%">71</TD><BR /> <TD style="width: 67.6953%">Click <STRONG>Environment Variables</STRONG>.</TD><BR /> <TD style="width: 23.4741%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/2-34.jpg" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 8.83053%">72</TD><BR /> <TD style="width: 67.6953%">Under <STRONG>System variables</STRONG>, click <STRONG>New</STRONG>.</TD><BR /> <TD style="width: 23.4741%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/3-6-1.jpg" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 8.83053%">73</TD><BR /> <TD style="width: 67.6953%"><BR /> <BR /> Enter <CODE>CCL_PROFILE</CODE> as the <STRONG>variable name</STRONG>.<BR /> <BR /> For the <STRONG>variable value</STRONG>, enter the full path to your <CODE>sapcrypto.ini</CODE> file, e.g. <CODE>C:\Program Files\On-premises data gateway\sapcrypto.ini</CODE><BR /> <BR /> Click <STRONG>OK</STRONG>.</TD><BR /> <TD style="width: 23.4741%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/3-7-2.jpg" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 8.83053%">74</TD><BR /> <TD style="width: 67.6953%">Click <STRONG>OK</STRONG>.</TD><BR /> <TD style="width: 23.4741%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/3-8-2.jpg" /></TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> <H3 id="toc-hId-109455448">Configure User Mappings in Active Directory</H3><BR /> To enable Kerberos-based principal propagation for a user in this scenario, a mapping from the user's full username (User Principal Name, UPN) in Azure AD to the user's local name in AD is required. For this purpose we will use the unused attribute<CODE>msDS-cloudExtensionAttribute1</CODE> of the local AD user to store the Azure AD UPN. Any other unused Active Directory attribute can be used as well.<BR /> <BR /> For the application test user <EM>Jack Davis</EM> in this scenario, you will set the <CODE>msDS-cloudExtensionAttribute1</CODE> attribute of the local AD domain user account <CODE>jdavis@corp.bestrun.com</CODE> to the user's Azure AD UPN <CODE>jdavis@bestruncorp.onmicrosoft.com</CODE> for linking his two accounts. The same applies to the application development user <EM>devuser</EM>, who requires a mapping from <CODE>devuser@corp.bestrun.com</CODE> to <CODE>devuser@bestruncorp.onmicrosoft.com</CODE>.<BR /> <TABLE style="border-collapse: collapse;width: 100%"><BR /> <TBODY><BR /> <TR style="height: 32px"><BR /> <TD style="width: 8.83053%;height: 32px"><STRONG>Step</STRONG></TD><BR /> <TD style="width: 67.6953%;height: 32px"><STRONG>Description</STRONG></TD><BR /> <TD style="width: 23.4741%;height: 32px"><STRONG>Screenshot</STRONG></TD><BR /> </TR><BR /> <TR style="height: 32px"><BR /> <TD style="width: 8.83053%;height: 32px">75</TD><BR /> <TD style="width: 67.6953%;height: 32px">On the gateway host, <STRONG>open</STRONG> the file <CODE>Microsoft.PowerBI.DataMovement.Pipeline.GatewayCore.dll.config</CODE> in the OPDG installation folder (<CODE>C:\Program Files\On-premises data gateway</CODE>) in an editor.</TD><BR /> <TD style="width: 23.4741%;height: 32px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/4-1-1-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">76</TD><BR /> <TD style="width: 67.6953%;height: 14px">Search for the setting <CODE>ADUserNameReplacementProperty</CODE> and set its value to&nbsp;<CODE>SAMAccountName</CODE>.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/4-2-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">77</TD><BR /> <TD style="width: 67.6953%;height: 14px"><BR /> <BR /> Search for the setting <CODE>ADUserNameLookupProperty</CODE> and set it to the value <CODE>msDS-cloudExtensionAttribute1</CODE>.<BR /> <BR /> <STRONG>Save</STRONG> the changes in the file.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/4-3-1-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 84px"><BR /> <TD style="width: 8.83053%;height: 84px">78</TD><BR /> <TD style="width: 67.6953%;height: 84px"><BR /> <BR /> Click <STRONG>Restart now</STRONG> from the OPDG's configurator <STRONG>Service Settings</STRONG> tab to apply the changes.<BR /> <BR /> &nbsp;</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/4-4-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 84px"><BR /> <TD style="width: 8.83053%;height: 84px">79</TD><BR /> <TD style="width: 67.6953%;height: 84px"><BR /> <BR /> On the Domain Controller host, click&nbsp;<STRONG>Start, </STRONG>and select <STRONG>Windows Administrative Tools →</STRONG>&nbsp;<STRONG>ADSI Edit </STRONG>from the menu.<BR /> <BR /> In the ADSI Editor, navigate in the left-side object tree to <STRONG>CN=Users</STRONG> under the domain's Default naming context.<BR /> <BR /> <STRONG>Right-click</STRONG> on the test user's object (e.g. <STRONG>CN=Jack Davis</STRONG>) and select <STRONG>Properties</STRONG> from the context menu.</TD><BR /> <TD style="width: 23.4741%;height: 84px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/4-5-1.jpg" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 8.83053%">80</TD><BR /> <TD style="width: 67.6953%">Select the attribute <CODE>msDS-cloudExtensionAttribute1</CODE> from the list and click <STRONG>Edit</STRONG>.</TD><BR /> <TD style="width: 23.4741%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/4-6-1.jpg" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 8.83053%">81</TD><BR /> <TD style="width: 67.6953%"><BR /> <BR /> Enter the test user's Azure AD UPN (e.g. <STRONG>jdavis@&lt;domainname&gt;.onmicrosoft.com</STRONG>) in the Value field.<BR /> <BR /> Replace <EM>&lt;domainname&gt;</EM> with your Azure AD tenant's domain name, e.g. <EM>bestruncorp</EM>.<BR /> <BR /> Click <STRONG>OK</STRONG>.</TD><BR /> <TD style="width: 23.4741%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/4-7-1.jpg" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 8.83053%">82</TD><BR /> <TD style="width: 67.6953%"><BR /> <BR /> Repeat steps 79 to 81 for the developer user object (e.g. <STRONG>CN=Developer User</STRONG>) and map it to the user's Azure AD UPN (e.g. <STRONG>devuser@&lt;domainname&gt;.onmicrosoft.com</STRONG>).via the <CODE>msDS-cloudExtensionAttribute1</CODE> attribute.<BR /> <BR /> Click <STRONG>OK</STRONG> and <STRONG>close</STRONG> the ADSI Editor.</TD><BR /> <TD style="width: 23.4741%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/4-8-2.jpg" /></TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> <H3 id="toc-hId--87058057">Configure SAP User Authorizations</H3><BR /> Next, the SAP system is configured for the application test user and power platform developer who need a different set of authorizations. The developer needs a set of authorizations used by the SAP ERP Connector for looking up the RFCs offered by the system during development of the Power Automate flow and at runtime. In addition, the application test user role requires the authorization to call the <CODE>BAPI_EPM_PRODUCT_GET_DETAILS</CODE> BAPI to search the product catalog with the Power App.<BR /> <TABLE style="border-collapse: collapse;width: 100%"><BR /> <TBODY><BR /> <TR style="height: 32px"><BR /> <TD style="width: 8.83053%;height: 32px"><STRONG>Step</STRONG></TD><BR /> <TD style="width: 67.6953%;height: 32px"><STRONG>Description</STRONG></TD><BR /> <TD style="width: 23.4741%;height: 32px"><STRONG>Screenshot</STRONG></TD><BR /> </TR><BR /> <TR style="height: 32px"><BR /> <TD style="width: 8.83053%;height: 32px">83</TD><BR /> <TD style="width: 67.6953%;height: 32px"><BR /> <BR /> Go back to SAP GUI and log in as the administrator user.<BR /> <BR /> Start transaction <STRONG>PFCG</STRONG> to define a new role for the application users in this scenario.</TD><BR /> <TD style="width: 23.4741%;height: 32px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-1-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 58px"><BR /> <TD style="width: 8.83053%;height: 58px">84</TD><BR /> <TD style="width: 67.6953%;height: 58px"><BR /> <BR /> Enter <CODE>PRODUCT_SEARCH_BAPI</CODE> in the <STRONG>Role</STRONG> field.<BR /> <BR /> Click <STRONG>Single Role</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 58px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-2-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 57px"><BR /> <TD style="width: 8.83053%;height: 57px">85</TD><BR /> <TD style="width: 67.6953%;height: 57px">Click <STRONG>Save</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 57px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-3-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 130px"><BR /> <TD style="width: 8.83053%;height: 130px">86</TD><BR /> <TD style="width: 67.6953%;height: 130px"><BR /> <BR /> Switch to the <STRONG>Authorization</STRONG> tab.<BR /> <BR /> Click the <STRONG>pencil</STRONG> button to edit the new role's authorization data.</TD><BR /> <TD style="width: 23.4741%;height: 130px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-4-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 102px"><BR /> <TD style="width: 8.83053%;height: 102px">87</TD><BR /> <TD style="width: 67.6953%;height: 102px">Click <STRONG>Do not select templates</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 102px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-5-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 42px"><BR /> <TD style="width: 8.83053%;height: 42px">88</TD><BR /> <TD style="width: 67.6953%;height: 42px">Click <STRONG>Manually</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 42px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-6-1-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 142px"><BR /> <TD style="width: 8.83053%;height: 142px">89</TD><BR /> <TD style="width: 67.6953%;height: 142px"><BR /> <BR /> Enter <CODE>S_RFC</CODE> for the <STRONG>Authorization Object</STRONG> in the first row.<BR /> <BR /> Click <STRONG>OK</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 142px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-7-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 56px"><BR /> <TD style="width: 8.83053%;height: 56px">90</TD><BR /> <TD style="width: 67.6953%;height: 56px">Click the <STRONG>pencil</STRONG> button to edit the authorization checks for field RFC_NAME.</TD><BR /> <TD style="width: 23.4741%;height: 56px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-8-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 133px"><BR /> <TD style="width: 8.83053%;height: 133px">91</TD><BR /> <TD style="width: 67.6953%;height: 133px">Enter the following values in the <STRONG>Value Intrvl</STRONG> table's <STRONG>'From'</STRONG> column:<BR /> <UL><BR /> <LI style="list-style-type: none"><BR /> <UL><BR /> <LI><CODE>BAPI_EPM_PRODUCT_GET_DETAILS</CODE></LI><BR /> <LI><CODE>RFCPING</CODE></LI><BR /> <LI><CODE>RFC_FUNCTION_SEARCH</CODE></LI><BR /> <LI><CODE>RFC_METADATA_GET</CODE></LI><BR /> </UL><BR /> </LI><BR /> </UL><BR /> Click <STRONG>Save</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 133px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/5-8-1-2.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 64px"><BR /> <TD style="width: 8.83053%;height: 64px">92</TD><BR /> <TD style="width: 67.6953%;height: 64px">Click the <STRONG>pencil</STRONG> button to edit the authorization checks for field Activity (ACTVT).</TD><BR /> <TD style="width: 23.4741%;height: 64px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-10-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 236px"><BR /> <TD style="width: 8.83053%;height: 236px">93</TD><BR /> <TD style="width: 67.6953%;height: 236px"><BR /> <BR /> Select <STRONG>Execute</STRONG> from the list.<BR /> <BR /> Click <STRONG>Save</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 236px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-11-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">94</TD><BR /> <TD style="width: 67.6953%;height: 14px">Click the <STRONG>pencil</STRONG> button to edit the authorization checks for field RFC_TYPE.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-12-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">95</TD><BR /> <TD style="width: 67.6953%;height: 14px"><BR /> <BR /> Select <STRONG>FUNC</STRONG> (Function Module) from the list.<BR /> <BR /> Click <STRONG>Save</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-13-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 63px"><BR /> <TD style="width: 8.83053%;height: 63px">96</TD><BR /> <TD style="width: 67.6953%;height: 63px">Click <STRONG>Save </STRONG>to save the application user role.</TD><BR /> <TD style="width: 23.4741%;height: 63px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-14-1-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 57px"><BR /> <TD style="width: 8.83053%;height: 57px">97</TD><BR /> <TD style="width: 67.6953%;height: 57px">Click <STRONG>Generate</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 57px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-15-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 75px"><BR /> <TD style="width: 8.83053%;height: 75px">98</TD><BR /> <TD style="width: 67.6953%;height: 75px">Click <STRONG>Exit</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 75px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-16-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">99</TD><BR /> <TD style="width: 67.6953%;height: 14px"><BR /> <BR /> Switch to the <STRONG>User</STRONG> tab.<BR /> <BR /> Enter your <STRONG>application test</STRONG> <STRONG>user's ID</STRONG> (e.g. JDAVIS) in the first row of the <STRONG>User Assignment</STRONG> table.<BR /> <BR /> Click <STRONG>Save</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-17-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">100</TD><BR /> <TD style="width: 67.6953%;height: 14px">Click <STRONG>User Comparison.</STRONG></TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-18-1-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">101</TD><BR /> <TD style="width: 67.6953%;height: 14px">Click <STRONG>Full Comparison</STRONG>, then <STRONG>Close</STRONG> the dialog window.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-19-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 35px"><BR /> <TD style="width: 8.83053%;height: 35px">102</TD><BR /> <TD style="width: 67.6953%;height: 35px">Click <STRONG>Exit</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 35px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-20-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 84px"><BR /> <TD style="width: 8.83053%;height: 84px">103</TD><BR /> <TD style="width: 67.6953%;height: 84px"><BR /> <BR /> Next, create the role for the application developer.<BR /> <BR /> Enter <CODE>PRODUCT_SEARCH_DEVELOPER</CODE> in the <STRONG>Role</STRONG> field.<BR /> <BR /> Click <STRONG>Single Role</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 84px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-21.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 241px"><BR /> <TD style="width: 8.83053%;height: 241px">104</TD><BR /> <TD style="width: 67.6953%;height: 241px"><BR /> <BR /> <STRONG>Repeat</STRONG> steps <STRONG>85</STRONG> to <STRONG>90</STRONG> for the new role.<BR /> <BR /> Enter the following values in the <STRONG>Value Intrvl</STRONG> table's <STRONG>'From'</STRONG> column:<BR /> <UL><BR /> <LI><CODE>DD_LANGU_TO_ISOLA</CODE></LI><BR /> <LI><CODE>RFCPING</CODE></LI><BR /> <LI><CODE>RFC_FUNCTION_SEARCH</CODE></LI><BR /> <LI><CODE>RFC_METADATA_GET</CODE></LI><BR /> </UL><BR /> Click <STRONG>Save</STRONG>.<BR /> <BR /> Continue by <STRONG>repeating</STRONG> steps <STRONG>92</STRONG>&nbsp;to <STRONG>98</STRONG>&nbsp;for the application developer role.</TD><BR /> <TD style="width: 23.4741%;height: 241px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-22.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 112px"><BR /> <TD style="width: 8.83053%;height: 112px">105</TD><BR /> <TD style="width: 67.6953%;height: 112px"><BR /> <BR /> Switch to the <STRONG>User</STRONG> tab.<BR /> <BR /> Enter your <STRONG>application test</STRONG> <STRONG>user's ID</STRONG> (e.g. DEVUSER) in the first row of the <STRONG>User Assignment</STRONG> table.<BR /> <BR /> Click <STRONG>Save</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 112px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-23.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">106</TD><BR /> <TD style="width: 67.6953%;height: 14px">Click <STRONG>User Comparison.</STRONG></TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-24.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">107</TD><BR /> <TD style="width: 67.6953%;height: 14px">Click <STRONG>Full Comparison</STRONG>, then <STRONG>Close</STRONG> the dialog window.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-19-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">108</TD><BR /> <TD style="width: 67.6953%;height: 14px">Click <STRONG>Exit</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/5-25-scaled.jpg" /></TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> <H3 id="toc-hId--283571562">Setup the Power Platform canvas app and flow</H3><BR /> All on-premise components (SAP system, OPDG, and AD) are now configured properly for Kerberos-based principal propagation of the Azure AD-authenticated user in the Power Platform canvas app which triggers the Power Automate flow to call the SAP system.<BR /> <BR /> In this step, you will import the application components as a solution in your Power Platform environment and configure them according to your test lab setup. If you want to deploy to a new environment for this scenario, go to <A href="https://admin.powerplatform.microsoft.com/environments" target="_blank" rel="nofollow noopener noreferrer">Power Platform admin center</A> and create it.<BR /> <TABLE style="border-collapse: collapse;width: 100%"><BR /> <TBODY><BR /> <TR style="height: 32px"><BR /> <TD style="width: 8.83053%;height: 32px"><STRONG>Step</STRONG></TD><BR /> <TD style="width: 67.6953%;height: 32px"><STRONG>Description</STRONG></TD><BR /> <TD style="width: 23.4741%;height: 32px"><STRONG>Screenshot</STRONG></TD><BR /> </TR><BR /> <TR style="height: 32px"><BR /> <TD style="width: 8.83053%;height: 32px">109</TD><BR /> <TD style="width: 67.6953%;height: 32px"><BR /> <BR /> <STRONG>Login</STRONG> to Power Apps Studio at <A href="https://make.powerapps.com" target="_blank" rel="nofollow noopener noreferrer"></A><A href="https://make" target="test_blank" rel="nofollow noopener noreferrer">https://make</A> powerapps.com with your Power Platform developer user.<BR /> <BR /> From the top <STRONG>menu</STRONG>, select the <A href="https://learn.microsoft.com/en-us/power-platform/admin/environments-overview" target="_blank" rel="nofollow noopener noreferrer">environment</A> to deploy the scenario components.</TD><BR /> <TD style="width: 23.4741%;height: 32px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/6-1-1-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 42px"><BR /> <TD style="width: 8.83053%;height: 42px">110</TD><BR /> <TD style="width: 67.6953%;height: 42px">Click <STRONG>Import solution</STRONG> from the top menu bar.</TD><BR /> <TD style="width: 23.4741%;height: 42px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-2-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 47px"><BR /> <TD style="width: 8.83053%;height: 47px">111</TD><BR /> <TD style="width: 67.6953%;height: 47px"><BR /> <BR /> Click <STRONG>Browse</STRONG> and select the file <CODE>SAPProductSearchSolution.zip</CODE> from the <A href="https://github.com/raepple/azure-scp-principal-propagation/tree/part7" target="_blank" rel="nofollow noopener noreferrer">Git repository's</A> <CODE>/ProductSearchApp</CODE> folder.<BR /> <BR /> Click <STRONG>Next</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 47px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-3-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 108px"><BR /> <TD style="width: 8.83053%;height: 108px">112</TD><BR /> <TD style="width: 67.6953%;height: 108px">Click <STRONG>Next</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 108px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-5-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 66px"><BR /> <TD style="width: 8.83053%;height: 66px">113</TD><BR /> <TD style="width: 67.6953%;height: 66px">Open the <STRONG>drop-down</STRONG> box and select <STRONG>New connection</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 66px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-6-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 42px"><BR /> <TD style="width: 8.83053%;height: 42px">114</TD><BR /> <TD style="width: 67.6953%;height: 42px"><BR /> <BR /> In the SAP ERP Connection dialog, select <STRONG>Azure AD integrated </STRONG>as the <STRONG>Authentication Type</STRONG>.<BR /> <BR /> In the <STRONG>Choose a gateway</STRONG> drop-down box, select your OPDG instance for this scenario.<BR /> <BR /> Click <STRONG>Create</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 42px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-7.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 84px"><BR /> <TD style="width: 8.83053%;height: 84px">115</TD><BR /> <TD style="width: 67.6953%;height: 84px"><BR /> <BR /> The new connection requires authentication to your Azure AD tenant.<BR /> <BR /> Click <STRONG>Fix connection</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 84px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-8-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 133px"><BR /> <TD style="width: 8.83053%;height: 133px">116</TD><BR /> <TD style="width: 67.6953%;height: 133px"><STRONG>Sign-in</STRONG> to your Azure AD tenant with your development user's account that you configured the SNC mapping in step 32 and AD mapping in step 82, and assigned the <CODE>PRODUCT_SEARCH_DEVELOPER</CODE> role in step 105.</TD><BR /> <TD style="width: 23.4741%;height: 133px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-9.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 57px"><BR /> <TD style="width: 8.83053%;height: 57px">117</TD><BR /> <TD style="width: 67.6953%;height: 57px">Upon successful sign-in, <STRONG>switch back</STRONG> to the previous browser tab.</TD><BR /> <TD style="width: 23.4741%;height: 57px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-10-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">118</TD><BR /> <TD style="width: 67.6953%;height: 14px">Click <STRONG>Refresh</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-11.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 102px"><BR /> <TD style="width: 8.83053%;height: 102px">119</TD><BR /> <TD style="width: 67.6953%;height: 102px"><BR /> <BR /> The new connection is now selected by the import solution wizard.<BR /> <BR /> Click <STRONG>Import</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 102px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-12.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 42px"><BR /> <TD style="width: 8.83053%;height: 42px">120</TD><BR /> <TD style="width: 67.6953%;height: 42px"><BR /> <BR /> Wait for the completion of the import as indicated by the green banner.<BR /> <BR /> Then <STRONG>select</STRONG> the imported <STRONG>SAP Product Search</STRONG> S<STRONG>olution</STRONG> from the list.</TD><BR /> <TD style="width: 23.4741%;height: 42px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-13-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 89px"><BR /> <TD style="width: 8.83053%;height: 89px">121</TD><BR /> <TD style="width: 67.6953%;height: 89px">From the solution components, <STRONG>select</STRONG> the <STRONG>SAPERPSettings</STRONG> environment variable. This variable is used by the SAP ERP connector action in the Power Automate flow to configure the SAP system connection parameters. It is in JSON format.</TD><BR /> <TD style="width: 23.4741%;height: 89px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-14-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 153px"><BR /> <TD style="width: 8.83053%;height: 153px">122</TD><BR /> <TD style="width: 67.6953%;height: 153px">Click <STRONG>New value</STRONG> to overwrite the default value.</TD><BR /> <TD style="width: 23.4741%;height: 153px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-15.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 87px"><BR /> <TD style="width: 8.83053%;height: 87px">123</TD><BR /> <TD style="width: 67.6953%;height: 87px">Enter the <STRONG>SAPERPSettings</STRONG> environment variable's new value according to your lab setup and the example below. You can use the default value as a template in a text editor.<BR /> <PRE class="language-perl"><CODE>{<BR /> "AppServerHost": "&lt;SAP system IP address or hostname, <BR /> e.g. 23.123.153.183&gt;",<BR /> "Client": "&lt;your client ID, e.g. 001&gt;",<BR /> "SystemNumber": "&lt;your system numner, e.g. 00",<BR /> "LogonType": "ApplicationServer",<BR /> "SncLibraryPath": "C:\\Program Files\\<BR /> On-premises data gateway\\sapcrypto.dll",<BR /> "SncPartnerName": "&lt;SAP system's SNC name, <BR /> e.g. 'p:CN=A4H'&gt;",<BR /> "SncQOP": "Default",<BR /> "SncSso": "On",<BR /> "SystemID": "&lt;SAP system's ID, e.g. A4H&gt;",<BR /> "UseSnc": "true"<BR /> }</CODE></PRE><BR /> Click <STRONG>Save</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 87px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-16-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 83px"><BR /> <TD style="width: 8.83053%;height: 83px">124</TD><BR /> <TD style="width: 67.6953%;height: 83px">Select the <STRONG>SAP Product Search</STRONG> canvas app from the solution.</TD><BR /> <TD style="width: 23.4741%;height: 83px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-17.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 117px"><BR /> <TD style="width: 8.83053%;height: 117px">125</TD><BR /> <TD style="width: 67.6953%;height: 117px"><BR /> <BR /> The Power Apps Studio opens the SAP Product Search canvas app in edit mode.<BR /> <BR /> Click <STRONG>Allow</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 117px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/6-14-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 126px"><BR /> <TD style="width: 8.83053%;height: 126px">126</TD><BR /> <TD style="width: 67.6953%;height: 126px"><BR /> <BR /> Select <STRONG>Power Automate</STRONG> from the left-side navigation menu to list the flows used by the canvas app.<BR /> <BR /> From the list, <STRONG>select</STRONG> the <STRONG>ellipsis ('…')</STRONG> next to the <STRONG>GetProductDetailsFromSAP</STRONG> flow.<BR /> <BR /> Click <STRONG>Refresh</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 126px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-19.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 81px"><BR /> <TD style="width: 8.83053%;height: 81px">127</TD><BR /> <TD style="width: 67.6953%;height: 81px">Click <B>Publish</B>.</TD><BR /> <TD style="width: 23.4741%;height: 81px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-20.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 83px"><BR /> <TD style="width: 8.83053%;height: 83px">128</TD><BR /> <TD style="width: 67.6953%;height: 83px">Click <STRONG>Publish this version</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 83px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-21-1.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 42px"><BR /> <TD style="width: 8.83053%;height: 42px">129</TD><BR /> <TD style="width: 67.6953%;height: 42px"><BR /> <BR /> You need to provide your application test user(s) access to the app.<BR /> <BR /> Click <STRONG>Share</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 42px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/6-15-1-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 42px"><BR /> <TD style="width: 8.83053%;height: 42px">130</TD><BR /> <TD style="width: 67.6953%;height: 42px"><BR /> <BR /> Enter your application test user's name (e.g. "Jack Davis") in the <STRONG>search field.</STRONG><BR /> <BR /> Click on the <STRONG>user account</STRONG>.<BR /> <BR /> <EM><STRONG>Note</STRONG></EM>: Instead of configuring single users, you can also type "Everyone" in the <STRONG>search filed</STRONG> and share the app with "Everyone in &lt;tenant org&gt;".</TD><BR /> <TD style="width: 23.4741%;height: 42px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/6-16.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 42px"><BR /> <TD style="width: 8.83053%;height: 42px">131</TD><BR /> <TD style="width: 67.6953%;height: 42px"><BR /> <BR /> <STRONG>Deactivate</STRONG> the checkbox <STRONG>Send an email invitation to the user</STRONG>.<BR /> <BR /> Click <STRONG>Share</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 42px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/6-17-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 42px"><BR /> <TD style="width: 8.83053%;height: 42px">132</TD><BR /> <TD style="width: 67.6953%;height: 42px"><STRONG>Close</STRONG> the <STRONG>Share</STRONG> dialog box.</TD><BR /> <TD style="width: 23.4741%;height: 42px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/6-18-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 42px"><BR /> <TD style="width: 8.83053%;height: 42px">133</TD><BR /> <TD style="width: 67.6953%;height: 42px">Click the <STRONG>Copy link to clipboard</STRONG> icon next to the app's <STRONG>Web link</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 42px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/6-19-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 42px"><BR /> <TD style="width: 8.83053%;height: 42px">134</TD><BR /> <TD style="width: 67.6953%;height: 42px"><BR /> <BR /> Since the SAP Product Search app uses the SAP ERP Connector which is <EM>Premium tier</EM> connector, the application test user requires a Power App license to use this app.<BR /> <BR /> In a new browser tab, open the <STRONG>Microsoft 365 admin center</STRONG> at <A href="https://admin.microsoft.com/" target="_blank" rel="nofollow noopener noreferrer">https://admin.microsoft.com/</A> and login as your Power Platform administrator.<BR /> <BR /> Select <STRONG>Billing → Licenses</STRONG> from the left-side navigation menu.<BR /> <BR /> Click <STRONG>Microsoft Power App Plan 2 Trial</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 42px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/6-20-scaled.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 133px"><BR /> <TD style="width: 8.83053%;height: 133px">135</TD><BR /> <TD style="width: 67.6953%;height: 133px"><BR /> <BR /> Click <STRONG>Assign licenses.</STRONG><BR /> <BR /> In the search box, enter your application test user's name and select the user's account from the list.<BR /> <BR /> Click <STRONG>Assign</STRONG>.<BR /> <BR /> You can now <STRONG>log out</STRONG> from the Microsoft 365 admin center.</TD><BR /> <TD style="width: 23.4741%;height: 133px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/6-21-scaled.jpg" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 8.83053%">136</TD><BR /> <TD style="width: 67.6953%"><BR /> <BR /> Similar to the canvas app, it is also required to set the user's permission to access the OPDG instance.<BR /> <BR /> Go to the <STRONG>Power Platform admin center</STRONG> at <A href="https://admin.powerplatform.microsoft.com" target="_blank" rel="nofollow noopener noreferrer">https://admin.powerplatform.microsoft.com</A>&nbsp;and login as your Power Platform admin user.<BR /> <BR /> Select <STRONG>Data (Preview)</STRONG> from the left-side navigation menu and switch to the <STRONG>On-premises data gateway</STRONG> tab.<BR /> <BR /> For the OPDG instance in your scenario, <STRONG>select</STRONG> the <STRONG>ellipsis ('…')</STRONG>. From the context menu, select <STRONG>Manage users</STRONG>.</TD><BR /> <TD style="width: 23.4741%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-27.jpg" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 8.83053%">137</TD><BR /> <TD style="width: 67.6953%"><BR /> <BR /> In the <STRONG>search field</STRONG>, start entering your application test user's name.<BR /> <BR /> Select the user's<STRONG> account</STRONG> from the list to <STRONG>add it</STRONG>.</TD><BR /> <TD style="width: 23.4741%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-28.jpg" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 8.83053%">138</TD><BR /> <TD style="width: 67.6953%">Click <STRONG>Share</STRONG>.</TD><BR /> <TD style="width: 23.4741%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-29.jpg" /></TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> <H3 id="toc-hId--480085067">Testing the scenario</H3><BR /> All required components are configured for testing the scenario in the following steps.<BR /> <TABLE style="border-collapse: collapse;width: 100%"><BR /> <TBODY><BR /> <TR style="height: 32px"><BR /> <TD style="width: 8.83053%;height: 32px"><STRONG>Step</STRONG></TD><BR /> <TD style="width: 67.6953%;height: 32px"><STRONG>Description</STRONG></TD><BR /> <TD style="width: 23.4741%;height: 32px"><STRONG>Screenshot</STRONG></TD><BR /> </TR><BR /> <TR style="height: 32px"><BR /> <TD style="width: 8.83053%;height: 32px">139</TD><BR /> <TD style="width: 67.6953%;height: 32px"><STRONG>Login</STRONG> to the domain on the workstation host with your application test user (e.g. CORP\jdavis).</TD><BR /> <TD style="width: 23.4741%;height: 32px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/05/1-8-1-1.jpg" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 8.83053%">140</TD><BR /> <TD style="width: 67.6953%">Open a <STRONG>web browser</STRONG> and <STRONG>paste</STRONG> the URL copied in step 133 into the address field.</TD><BR /> <TD style="width: 23.4741%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/7-2.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">141</TD><BR /> <TD style="width: 67.6953%;height: 14px">Since you have synchronized your AD users with Azure AD Connect, you are <STRONG>single signed-on</STRONG> with the application test user to your Azure AD tenant and the app is loaded.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/7-3.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 99px"><BR /> <TD style="width: 8.83053%;height: 99px">142</TD><BR /> <TD style="width: 67.6953%;height: 99px"><BR /> <BR /> The SAP ERP connector requires a connection on-behalf-of the authenticated user.<BR /> <BR /> Click <STRONG>Allow</STRONG> to give consent to the requested permission to use this connection.</TD><BR /> <TD style="width: 23.4741%;height: 99px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/7-5.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 139px"><BR /> <TD style="width: 8.83053%;height: 139px">143</TD><BR /> <TD style="width: 67.6953%;height: 139px"><BR /> <BR /> Enter a <STRONG>product ID</STRONG> form the catalog in the entry field, e.g. AR-FB-1000.<BR /> <BR /> Click <STRONG>Search</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 139px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/7-4.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 105px"><BR /> <TD style="width: 8.83053%;height: 105px">144</TD><BR /> <TD style="width: 67.6953%;height: 105px">The app triggers the flow which calls the SAP system on-behalf-of the Azure AD-authenticated user. The SAP ERP connector obtains a Kerberos ticket from Active Directory for the user found in the <CODE>msDS-cloudExtensionAttribute1</CODE> attribute. Upon receiving the Kerberos ticket with the BAPI call, the SAP system is able to map the AD user via the SNC mapping to a local user in the system, for whom it checks the proper authorizations to invoke the BAPI. Finally, the response with the product details is returned to the Power Automate flow, which parses the response and sends the price information back to the canvas app.</TD><BR /> <TD style="width: 23.4741%;height: 105px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/7-6.jpg" /></TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> <STRONG>Congratulations</STRONG>! You've successfully completed the scenario. The following sections provide additional information about optional settings to improve the end user's experience, configure for load balancing, and some troubleshooting tips.<BR /> <H3 id="toc-hId--676598572">Bypass the user consent</H3><BR /> In step 142, the user has been asked to confirm the requested permissions of the SAP ERP Connector. In most enterprise scenarios, this user consent is usually not required, and can be bypassed with the following Powershell commands for Power apps administration:<BR /> <TABLE style="border-collapse: collapse;width: 100%"><BR /> <TBODY><BR /> <TR style="height: 32px"><BR /> <TD style="width: 8.83053%;height: 32px"><STRONG>Step</STRONG></TD><BR /> <TD style="width: 67.6953%;height: 32px"><STRONG>Description</STRONG></TD><BR /> <TD style="width: 23.4741%;height: 32px"><STRONG>Screenshot</STRONG></TD><BR /> </TR><BR /> <TR style="height: 32px"><BR /> <TD style="width: 8.83053%;height: 32px">145</TD><BR /> <TD style="width: 67.6953%;height: 32px"><BR /> <BR /> <STRONG>Start</STRONG> a Windows Powershell as an administrator.<BR /> <BR /> Import the necessary modules using the following commands:<BR /> <BR /> <CODE>Install-Module -Name Microsoft.PowerApps.Administration.PowerShell</CODE><BR /> <BR /> <CODE>Install-Module -Name Microsoft.PowerApps.PowerShell -AllowClobber</CODE><BR /> <BR /> <STRONG>Confirm</STRONG> the questions with "Y".</TD><BR /> <TD style="width: 23.4741%;height: 32px"><BR /> <BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/8-1-1.jpg" /><BR /> <BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/8-2.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">146</TD><BR /> <TD style="width: 67.6953%;height: 14px"><BR /> <BR /> Provide your Power Platform administrator credentials using the following command:<BR /> <BR /> <CODE>Add-PowerAppsAccount</CODE><BR /> <BR /> &nbsp;</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/8-3.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">147</TD><BR /> <TD style="width: 67.6953%;height: 14px">The command <STRONG>opens the prompt</STRONG> to collect your Power Platform administrator credentials.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/8-4.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 8.83053%;height: 14px">148</TD><BR /> <TD style="width: 67.6953%;height: 14px"><BR /> <BR /> Run the Power Apps cmdlet<BR /> <BR /> <CODE>Get-AdminPowerAppEnvironment</CODE><BR /> <BR /> and copy the value for your scenario's <STRONG>EnvironmentName</STRONG> to a temporary textfile.</TD><BR /> <TD style="width: 23.4741%;height: 14px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/8-5.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 28px"><BR /> <TD style="width: 8.83053%;height: 28px">149</TD><BR /> <TD style="width: 67.6953%;height: 28px"><BR /> <BR /> Run the Power Apps cmdlet<BR /> <BR /> <CODE>Get-AdminPowerApp -EnvironmentName &lt;value from step 148&gt;</CODE><BR /> <BR /> with the value obtained in the previous step.<BR /> <BR /> Copy the value for your app's <STRONG>AppName</STRONG> to the temporary textfile.</TD><BR /> <TD style="width: 23.4741%;height: 28px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/8-6.jpg" /></TD><BR /> </TR><BR /> <TR style="height: 64px"><BR /> <TD style="width: 8.83053%;height: 64px">150</TD><BR /> <TD style="width: 67.6953%;height: 64px"><BR /> <BR /> With the two values for <STRONG>EnvironmentName</STRONG> and <STRONG>AppName</STRONG> run the command:<BR /> <BR /> <CODE>Set-AdminPowerAppApisToBypassConsent -EnvironmentName &lt;value from step 148&gt; -AppName &lt;value from step 149&gt;</CODE><BR /> <BR /> This command changes the <CODE>bypassConsent</CODE> flag of the SAP Product Search app to <STRONG>true</STRONG>.</TD><BR /> <TD style="width: 23.4741%;height: 64px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/8-7.jpg" /></TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> <H3 id="toc-hId--948343446">Configure Load Balancing via SAP Message Server</H3><BR /> In step 123, the connection parameters are configured for a specific application server instance. While this setup is appropriate for development and testing purposes, it may not be the preferred choice in a production environment. There the SAP landscape usually runs an SAP Message Server which load-balances the RFC calls to multiple application servers.<BR /> <BR /> If you want to setup the scenario for load balancing via SAP Message Server, change the <STRONG>SAPERPSettings</STRONG> environment variable according to the following template:<BR /> <PRE class="language-perl"><CODE>{<BR /> "MessageServerHost": "&lt;SAP Message Server address or hostname, e.g. 23.123.153.183&gt;",<BR /> "Client": "&lt;your client ID, e.g. 001&gt;",<BR /> "LogonType": "Group",<BR /> "MessageServerService": "&lt;The service name or port number that the Message Server is listening under for load balancing requests, e.g. 3601&gt;",<BR /> "SncLibraryPath": "C:\\Program Files\\On-premises data gateway\\sapcrypto.dll",<BR /> "SncPartnerName": "&lt;SAP system's SNC name, e.g. 'p:CN=A4H'&gt;",<BR /> "SncQOP": "Default",<BR /> "SncSso": "On",<BR /> "SystemID": "&lt;SAP system's ID, e.g. A4H&gt;",<BR /> "UseSnc": "true"<BR /> }</CODE></PRE><BR /> Here is an example of a valid connection string using SAP Message Server. You can use transaction <CODE>SMMS</CODE> (Message Service Monitor) to find the correct value for parameter <CODE>MessageServerService</CODE>:<BR /> <PRE class="language-perl"><CODE>{<BR /> "MessageServerHost": "20.123.153.183",<BR /> "Client": "001",<BR /> "LogonType": "Group",<BR /> "MessageServerService": "3601",<BR /> "SncLibraryPath": "C:\\Program Files\\On-premises data gateway\\sapcrypto.dll",<BR /> "SncPartnerName": "p:CN=A4H",<BR /> "SncQOP": "Default",<BR /> "SncSso": "On",<BR /> "SystemID": "A4H",<BR /> "UseSnc": "true"<BR /> }</CODE></PRE><BR /> <H3 id="toc-hId--1144856951">Troubleshooting</H3><BR /> In complex integration scenarios across various system-, network- and technology-boundaries, troubleshooting usually starts with gathering information about <EM>what</EM> the issue is and <EM>where</EM> it occurs. Therefore the techniques in this last section start with troubleshooting the scenario from the user's perspective and then explain how to obtain detailed error traces from the system components along the end-to-end communication path.<BR /> <H4 id="toc-hId--1634773463">Debugging with the Power Platform tools</H4><BR /> To starting debugging the application scenario, <STRONG>login</STRONG> to <A href="https://make.powerautomate.com" target="_blank" rel="nofollow noopener noreferrer"></A><A href="https://make" target="test_blank" rel="nofollow noopener noreferrer">https://make</A> powerautomate.com with your Power Platform developer user. Select <STRONG>My flows</STRONG> from the left-side navigation menu and click on the <STRONG>Run button</STRONG> of the <STRONG>GetProductDetailsFromSAP</STRONG> flow. You can enter a <STRONG>product ID</STRONG> to search for in the entry field and click <STRONG>Run flow</STRONG> to start a new instance of the flow (figure 4):<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/11-1-scaled.jpg" height="271" width="541" /><BR /> <BR /> Figure 4: <EM>Manually triggering the flow in the scenario</EM><BR /> <BR /> In the confirmation dialog box (figure 5), click the <STRONG>Flow Runs Page</STRONG> link. This page shows the run history of the <STRONG>GetProductDetailsFromSAP</STRONG> flow. Click on the fist item in the list to see the results from the last run. As shown in the following screenshot, the 3rd step Call <STRONG>SAP function (V2) - BAPI EPM PRODUCT GET DETAIL</STRONG> failed with a <EM>BadGateway</EM> error. By clicking on <STRONG>Show raw outputs</STRONG> you can view more details about the underlying issue. The user who started the instance (in this case the Power Platform developer user) obviously didn't have the required permissions in the SAP system to call the BAPI according to the exception message:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/12-2-scaled.jpg" /></P><BR /> Figure 5: <EM>Monitor flow run</EM><BR /> <BR /> Lower-level issues such as Kerberos- or user-mapping-related problems are usually reported back to the flow as an <STRONG>InternalServerError </STRONG>by the SAP ERP Connector. In this case you should take a closer look at the available error traces in the different log files.<BR /> <H4 id="toc-hId--1831286968">SNC and Kerberos troubleshooting</H4><BR /> A good starting point for troubleshooting SNC and Kerberos is the <A href="https://gad5158842f.us2.hana.ondemand.com/dtp/viewer/#/tree/1764/actions/22794" target="_blank" rel="nofollow noopener noreferrer">Guided Answers wizard for SNC Kerberos Configuration for SAP GUI troubleshooting.</A> In addition, the following (non-complete) list of SAP Notes also provides resolutions for common SNC-related problems:<BR /> <UL><BR /> <LI><A href="https://me.sap.com/notes/1635019" target="_blank" rel="noopener noreferrer">1635019: No user exists with SNC name - canonical name not resolved</A></LI><BR /> <LI><A href="https://me.sap.com/notes/1696905" target="_blank" rel="noopener noreferrer">1696905: SNC name configuration to support Kerberos and Certificates</A></LI><BR /> <LI><A href="https://me.sap.com/notes/1848999" target="_blank" rel="noopener noreferrer">1848999: Central Note for CommonCryptoLib 8 (SAPCRYPTOLIB)</A></LI><BR /> <LI><A href="https://me.sap.com/notes/1878155" target="_blank" rel="noopener noreferrer">1878155: SNC Error Code A2210231: Kerberos ticket not yet valid</A></LI><BR /> <LI><A href="https://me.sap.com/notes/2265085" target="_blank" rel="noopener noreferrer">2265085: Unable to load GSS-API DLL sapcrypto.dll</A></LI><BR /> <LI><A href="https://me.sap.com/notes/2384027" target="_blank" rel="noopener noreferrer">2384027: Error A2210233:Kerberos ticket contains wrong service name target</A></LI><BR /> <LI><A href="https://me.sap.com/notes/2446327" target="_blank" rel="noopener noreferrer">2446327: SNC Error Code A221021D Server refuses offered key exchange algorithm</A></LI><BR /> <LI><A href="https://me.sap.com/notes/2497505" target="_blank" rel="noopener noreferrer">2497505: SNC Error Code A2200210 Peer certificate verification failed - Kerberos configuration</A></LI><BR /> </UL><BR /> Turning on SNC traces for SAP NCo and the SAP system can further help with the root cause analysis:<BR /> <UL><BR /> <LI>On the SAP system, login as the operating system administrator, and change to the directory where the SAP Cryptographic Library is loaded from, e.g <CODE>/usr/sap/&lt;SID&gt;/&lt;INST&gt;/exe</CODE>, and create a new text file named <CODE>sectrace.ini</CODE> with the following content:<BR /> <PRE class="language-markup"><CODE>LEVEL=4<BR /> DIRECTORY=&lt;new-or-empty-subfolder&gt;​</CODE></PRE><BR /> <CODE>DIRECTORY</CODE> must be set to a valid folder name for the respective platform. It must be the subfolder of an existing one, and should be placed in a local drive. If <CODE>DIRECTORY</CODE> doesn't exist it will be created. As an example, <CODE>DIRECTORY</CODE> can be set on a Linux system to <EM><CODE>/usr/sap/&lt;SID&gt;/&lt;INST&gt;/sectrace</CODE>.<BR /> </EM>The following screenshot shows the traces generated in file <CODE>sec-disp+work-&lt;nnnnnn&gt;.trc</CODE> by the SAP GUI login of the application test user in step 37:<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/4-8.jpg" /></LI><BR /> <LI>To enable SNC tracing on the OPDG, open the <CODE>sapcrypto.ini</CODE> (see step 68) and add the following two lines to it:<BR /> <PRE class="language-markup"><CODE>ccl/trace/level=4<BR /> ccl/trace/directory=C:\snctrc​</CODE></PRE><BR /> Generated trace files can be found in the directory specified by the <CODE>ccl/trace/directory</CODE> profile parameter.</LI><BR /> </UL><BR /> As the size of the generated trace files may grow quickly and tracing also reduces the performance of the systems, it is recommended to remove <CODE>sectrace.ini</CODE> and/or the <A href="https://me.sap.com/notes/2338952" target="_blank" rel="noopener noreferrer">configuration profile parameters</A> from <CODE>sapcrypto.ini</CODE> once the troubleshooting activities are completed.<BR /> <BR /> An in-depth analysis of the Kerberos message exchange between OPDG and SAP is possible with <A href="https://www.wireshark.org/download.html" target="_blank" rel="nofollow noopener noreferrer">Wireshark</A>, a tool for capturing and analyzing network traffic. Install the tool on the OPDG host and follow the steps below to capture the Kerberos taffic of steps 10 to 14 from figure 2:<BR /> <TABLE style="border-collapse: collapse;width: 100%" border="1"><BR /> <TBODY><BR /> <TR><BR /> <TD style="width: 66%"><BR /> <BR /> Launch <STRONG>Wireshark</STRONG>.<BR /> <BR /> Select the network interface(s), e.g. <STRONG>Ethernet</STRONG>, to capture traffic for, and click on <STRONG>Start capturing packets</STRONG>.</TD><BR /> <TD style="width: 34%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/6-24.jpg" height="129" width="199" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 66%"><STRONG>Run</STRONG> the application scenario (steps 139 to 144)</TD><BR /> <TD style="width: 34%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/7-8.jpg" height="134" width="174" /></TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 66%"><BR /> <BR /> Enter "<STRONG>kerberos</STRONG>" in the <STRONG>display filter</STRONG> field and press <STRONG>Enter</STRONG>.<BR /> <BR /> In the captured messages filtered for the Kerberos protocol, look for any error messages.<BR /> <BR /> The screenshot shows the <CODE>TGS_REQ</CODE> message (figure 2, step 12) with the user's service ticket for OPDG obtained in the previous step as an <CODE>additional-ticket</CODE> in the request.</TD><BR /> <TD style="width: 34%"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/8-9.jpg" height="129" width="178" /></TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> <H4 id="toc-hId--2027800473">Collecting the logs from OPDG</H4><BR /> Launch the OPDG app (see step 54) and sign-in as the Power Platform administrator. Select&nbsp;<STRONG>Diagnostics</STRONG> and click <STRONG>Export logs</STRONG> as shown in figure 6:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/9-1.jpg" height="174" width="284" /></P><BR /> Figure 6: <EM>Exporting OPDG logs</EM><BR /> <BR /> Unzip the file that is saved to the <CODE>ODGLogs</CODE> folder on your Windows desktop. Look for the most recent <CODE>GatewayErrors*</CODE> file in the archive. The following screenshot shows the log file with an error message that the SAP Cryptographic Library could not be found in the OPDG installation directory:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/10-1.jpg" height="300" width="332" /></P><BR /> Figure 7: <EM>OPDG log excerpt</EM><BR /> <H4 id="toc-hId-2070653318">Other common issues</H4><BR /> Finally, table 2 contains a non-complete list of common error message in the scenario and suggests possible ways to resolve them.<BR /> <TABLE style="border-collapse: collapse;width: 100%"><BR /> <TBODY><BR /> <TR style="height: 32px"><BR /> <TD style="width: 47.2675%;height: 32px">If you see this ...</TD><BR /> <TD style="width: 53.0869%;height: 32px">... try this:</TD><BR /> </TR><BR /> <TR style="height: 32px" valign="top"><BR /> <TD style="width: 47.2675%;height: 32px"><BR /> <BR /> When signing on to the Power app, the error message PowerPINotAuthorizedException is shown:<BR /> <BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/1-6.jpg" /></TD><BR /> <TD style="width: 53.0869%;height: 32px"><BR /> <BR /> Go to Power Platform admin center at <A href="https://admin.powerplatform.microsoft.com" target="_blank" rel="nofollow noopener noreferrer">https://admin.powerplatform.microsoft.com</A> and login as your Power Platform admin user.<BR /> <BR /> Select Data (Preview) from the left-side navigation menu and switch to the On-premises data gateway tab.<BR /> <BR /> For the OPDG instance in your scenario, select the ellipsis ('…'). From the context menu, select Manage users.<BR /> <BR /> Check if the user you signed-on to the app is in the list of users assigned to the Connection Creator role of the gateway and that the SAP ERP Connection type is activated.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/2-4.jpg" /></P><BR /> </TD><BR /> </TR><BR /> <TR style="height: 475px"><BR /> <TD style="width: 47.2675%;height: 475px">When executing the search, a <STRONG>No RFC authorization</STRONG> error message is shown:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/3-3.jpg" /></P><BR /> </TD><BR /> <TD style="width: 53.0869%;height: 475px"><BR /> <BR /> An error in the app indicating an RFC authorization issue can be fixed by checking the correct role design (steps 83ff) and the assignment to the user (step 99).<BR /> <BR /> To troubleshoot authorization problems of the propagated principal in the backend start a system trace as the SAP admin with transaction <STRONG>ST01</STRONG> as shown in the screenshot below. Select <STRONG>Authorization checks</STRONG> from the Trace Components and click <STRONG>Trace on</STRONG>.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/13.jpg" /></P><BR /> Re-run the scenario and click <STRONG>Trace off</STRONG>, then <STRONG>Anaysis</STRONG>. On the next screen, enter "*" for the user name and click <STRONG>Start Reporting (F8)</STRONG>:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/14-2-scaled.jpg" /></P><BR /> The orange-colored lines in the report show failed authorization checks due to missing permissions of the user in the system.</TD><BR /> </TR><BR /> <TR><BR /> <TD style="width: 47.2675%"><BR /> <DIV><BR /> <DIV><STRONG>GatewayTimeout</STRONG> caused by&nbsp;<STRONG>SAP system connection timeout</STRONG> with the message "<STRONG>partner '&lt;IP address of SAP system&gt;:48&lt;instance number&gt;' not reached</STRONG>"</DIV><BR /> </DIV><BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/15-1.jpg" /><BR /> <P style="overflow: hidden;margin-bottom: 0px"></P><BR /> </TD><BR /> <TD style="width: 53.0869%">Make sure that <STRONG>port 48&lt;instance number&gt;</STRONG> (e.g. 4800) on the SAP system can be reached from the OPDG. In case you deployed a <A href="https://cal.sap.com/" target="_blank" rel="noopener noreferrer">CAL instance</A> on Azure, check the <STRONG>Network security group</STRONG> (NSG) settings on the <EM>subnet</EM> and <EM>network interface</EM> level for corresponding rules to allow network traffic over this port as shown in the following screenshot:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/16-3-scaled.jpg" /></P><BR /> </TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> Table 2: <EM>Common error message and their possible resolution</EM><BR /> <BR /> &nbsp; 2023-06-19T13:52:16+02:00 https://community.sap.com/t5/enterprise-resource-planning-blogs-by-members/from-zero-to-hero-security-coverage-with-microsoft-sentinel-for-your/ba-p/13553737 From zero to hero security coverage with Microsoft Sentinel for your critical SAP security signals – Part 4 2023-07-06T10:42:19+02:00 Martin-Pankraz https://community.sap.com/t5/user/viewprofilepage/user-id/143781 <TABLE border="1"><TBODY><TR><TD><STRONG><span class="lia-unicode-emoji" title=":backhand_index_pointing_right:">👉🏿</span>back to <A href="https://blogs.sap.com/2023/05/22/from-zero-to-hero-security-coverage-with-microsoft-sentinel-for-your-critical-sap-security-signals-blog-series/" target="_blank" rel="noopener noreferrer">blog series</A> or to GitHub <A href="https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/SAP/Playbooks" target="_blank" rel="noopener nofollow noreferrer">repos</A> with ready-to-run playbooks.</STRONG></TD></TR></TBODY></TABLE><P><SPAN>Dear community,</SPAN><BR /><BR />There are various problematic attack vectors for SAP backends, but only a few are as severe as losing access to the SAP audit log from your security tooling. In <A href="https://blogs.sap.com/2023/05/23/from-zero-to-hero-security-coverage-with-microsoft-sentinel-for-your-critical-sap-security-signals-part-3/" target="_blank" rel="noopener noreferrer">part 3</A> we discussed malicious deactivation of the SAP audit log. Now, what if the SAP RFC user to collect the audit log info gets locked, deleted, or disabled in any other way too?<BR /><BR />At that point you are <STRONG>fully blind</STRONG> and might <STRONG>not even get the audit-log deactivation message anymore</STRONG> if the attacker is fast.<BR /><BR />Today you will see an automated response flow to <STRONG>deal with that situation</STRONG>. But wait!<BR /><BR />How about regular SAP or Sentinel Collector VM maintenance? How do we <STRONG>distinguish between normal operations and actual attacks?</STRONG><BR /><BR />Stay tuned – <A href="https://learn.microsoft.com/azure/sap/center-sap-solutions/overview" target="_blank" rel="noopener nofollow noreferrer">Azure Center for SAP solutions</A> (ACSS) comes to the rescue<span class="lia-unicode-emoji" title=":dog:">🐕</span>‍🦺<span class="lia-unicode-emoji" title=":rescue_workers_helmet:">⛑</span>️ to wade through the false positives and emphasize the impactful true positives.</P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/07/collector-attack-overview.png" border="0" /></P><P>Fig.1 Overview remediation workflow for the Sentinel Collector attack scenario powered by ACSS</P><H1 id="toc-hId-832999307">Cyber-attacks require the quickest possible reaction</H1><P>The <A href="https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/SAP/Playbooks/SAPCollectorRemediate-STD" target="_blank" rel="noopener nofollow noreferrer">provided playbook</A> posts an <A href="https://adaptivecards.io/" target="_blank" rel="noopener nofollow noreferrer">adaptive card</A> to Microsoft Teams with a color-coded message <STRONG>scoring the likelihood of an attack</STRONG> based on the signals coming from <A href="https://learn.microsoft.com/azure/sentinel/sap/sap-solution-log-reference" target="_blank" rel="noopener nofollow noreferrer">the Sentinel Collector for SAP</A>, and the SAP system state. The Azure Center for SAP Solutions provides a set of managed APIs to query such info in a scalable and secure way.<BR /><BR />The playbook is wired to listen to the pre-built Sentinel alert “<A href="https://learn.microsoft.com/en-us/azure/sentinel/monitor-sap-system-health#use-an-alert-rule-template" target="_blank" rel="noopener nofollow noreferrer">SAP - Data collection health check</A>”. But you may customize yourself to whatever scenario you need.<BR /><BR />In the scenario depicted in fig.1 the Sentinel Collector for SAP is healthy while SAP is running fine too.<BR /><BR />That causes the playbook to <STRONG>raise the attack likelihood</STRONG> based on the alert “RFC LOGON FAILURE” to medium. After all there is still a little chance that someone unintentionally performed a breaking user setup change. Up to you to configure this as “high” or “<STRONG>OMG run for your lives</STRONG>” based on how likely you think that is in your landscape.<BR /><BR />See <A href="https://learn.microsoft.com/azure/sap/center-sap-solutions/quickstart-register-system-cli" target="_blank" rel="noopener nofollow noreferrer">here</A> how to <STRONG>register your SAP system with ACSS</STRONG> and be ready for upcoming out of the box integrations.</P><TABLE border="1"><TBODY><TR><TD>In case the <STRONG>Collector or SAP would have been down</STRONG>, the <STRONG>likelihood of attack</STRONG> gets set to <STRONG>low</STRONG> with the suggestion to double check and investigate further through Sentinel, since this likely a planned maintenance or an outage.<BR /><BR />See <A href="https://www.youtube.com/watch?v=IO1cNyAJcYI&amp;t=1510s" target="_blank" rel="noopener nofollow noreferrer">here</A> how to <STRONG>communicate SAP maintenance via Microsoft Teams</STRONG> in an interactive way. <A href="https://youtu.be/IO1cNyAJcYI?t=1667" target="_blank" rel="noopener nofollow noreferrer">Integration with the SharePoint list</A> using the SID known to Sentinel enables you to enhance the presented flow further.<BR /><BR />What else would you like to see here? Reach out or let me know in the comments.</TD></TR></TBODY></TABLE><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/07/collector-attack-card.png" border="0" /></P><P>Fig.2 Screenshot of adaptive card with Sentinel’s SAP incident in Microsoft Teams</P><P>As per the inferred info from the various sources, the playbook suggests a couple of options to remediate the situation. This is customizable according to your needs.</P><H2 id="toc-hId-765568521">Let the community know what additional remediation paths you would like to see here. Happy to dive deeper.</H2><P>The simplest option addresses the possible process glitch on the Collector VM. Hit the corresponding button (see lower section on above screenshot) to trigger an automatic restart of the VM.</P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/07/collector-attack-vm-restart.png" border="0" width="342" height="393" /></P><P>Fig.3 Screenshot of Sentinel Collector VM restart logic<BR /><BR />This suggested remediations (see fig.2) are a natural fit for the upcoming <A href="https://www.microsoft.com/security/business/ai-machine-learning/microsoft-security-copilot" target="_blank" rel="noopener nofollow noreferrer">Microsoft Security Copilot</A>. Will get into details once it gets more widely available.</P><H2 id="toc-hId-569055016">The true power lies in the correlation of multiple signals&nbsp; in addition to the ACSS metadata leading to the event of the SAP Collector being "blinded"</H2><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/07/collector-attack-correlation.png" border="0" /></P><P>Fig.4 Screenshot from Sentinel security video series about multi-staged attacks to SAP</P><P>In the above scenario you can see a sequence of alerts painting the <STRONG>larger picture of the attack</STRONG> from RDP activity to login attempts in various places leading to a successful data download from SAP sending the file to an unknown IP address. In addition to that <A href="https://learn.microsoft.com/defender/threat-intelligence/what-is-microsoft-defender-threat-intelligence-defender-ti" target="_blank" rel="noopener nofollow noreferrer">Microsoft Defender</A> already compiled <STRONG>which attacker group was responsible</STRONG> based on the attack footprint, techniques and tools used.<BR /><BR />See the full video <A href="https://www.youtube.com/watch?v=JcPleCK5AJE&amp;t=652s" target="_blank" rel="noopener nofollow noreferrer">here</A>.</P><H1 id="toc-hId-243458792">Additional automation scenarios</H1><P>Another popular RFC attack vector (<A href="https://wiki.scn.sap.com/wiki/display/Security/Note+3089413+-+Capture-replay+vulnerability+in+SAP+NetWeaver+AS+for+ABAP+and+ABAP+Platform" target="_blank" rel="noopener noreferrer">Capture-Replay vulnerability</A> in NetWeaver AS for ABAP; SAP security Note <A href="https://me.sap.com/notes/3089413/E" target="_blank" rel="noopener noreferrer">3089413</A>) can be addressed like <A href="https://techcommunity.microsoft.com/t5/microsoft-sentinel-blog/detect-capture-replay-vulnerabilities-amp-exploits-with-the/ba-p/3727644" target="_blank" rel="noopener nofollow noreferrer">this</A>. How about blocking the user corresponding to that new SAP system connection? Have a look at <A href="https://blogs.sap.com/2023/05/22/from-zero-to-hero-security-coverage-with-microsoft-sentinel-for-your-critical-sap-security-signals-youre-gonna-hear-me-soar-part-1/" target="_blank" rel="noopener noreferrer">part 1</A> of the series.<BR /><BR />Last weeks publication in the <A href="https://www.heise.de/news/SAP-Authentifizierungs-Konzept-mit-Maengeln-9203990.html" target="_blank" rel="noopener nofollow noreferrer">German SAP security tech press</A> re-inforces the need to deal with RFC vulnerabilites. Would you like to get the recommended security setting change for the function module "<SPAN class="">RFC_TRUSTED_SYSTEM_SECURITY</SPAN>" to be performed automatically from such a workflow? Or would you consider that too high a risk because it could be used to attack from a different angle?<BR /><BR />Part 4 concludes the first wave of my blog series.<BR /><BR />Looking to you now to request additional scenarios and share your own as <A href="https://github.com/Azure/Azure-Sentinel" target="_blank" rel="noopener nofollow noreferrer">Pull Requests</A> on GitHub.</P><H1 id="toc-hId-46945287">Final words</H1><P>That’s a wrap <span class="lia-unicode-emoji" title=":burrito:">🌯</span>today you saw another SAP security automation scenario in action. We <A href="https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/SAP/Playbooks/SAPCollectorRemediate-STD" target="_blank" rel="noopener nofollow noreferrer">deployed a playbook</A> that <STRONG>scores potential attacks to the audit log ingestion pipeline of Microsoft Sentinel</STRONG>. The required signals to determine the severity of the alert are fed by <A href="https://learn.microsoft.com/azure/sap/center-sap-solutions/overview" target="_blank" rel="noopener nofollow noreferrer">Azure Center for SAP solutions</A> to get reliable information about the operational state of SAP.<BR /><BR />In case all involved systems are up and running while only audit log ingestion is impacted, there is a considerable chance for an ongoing attack. The playbook offers<STRONG> pre-configured actions to act immediately directly from Microsoft Teams</STRONG>.<BR /><BR />That <STRONG>brings down the time to action</STRONG> while avoiding to “shoot” from the hip with security incidents when SAP is just down for maintenance. Whooza, whoooza Sentinel. Nothing to worry about 🧘🏻 ☮<BR /><BR />This integration pattern overall is <STRONG>applicable to any SAP API</STRONG>. Got another SAP threat at your hands that needs automatic remediation? Let me know in the comments or reach out directly.<BR /><BR />Cheers<BR />Martin</P> 2023-07-06T10:42:19+02:00 https://community.sap.com/t5/technology-blogs-by-sap/call-node-js-or-python-functions-from-abap/ba-p/13572286 Call Node.js or Python Functions from ABAP 2023-08-25T16:45:09+02:00 Srdjan https://community.sap.com/t5/user/viewprofilepage/user-id/174007 Node.js rich ecosystem offers plenty of functions and utilities. Using <A href="https://github.com/SAP/node-rfc" target="_blank" rel="nofollow noopener noreferrer">node-rfc</A> server bindings, these assets can be consumed from ABAP, just like standard ABAP functions. SAP Open Source <A href="https://github.com/SAP/node-rfc" target="_blank" rel="nofollow noopener noreferrer">node-rfc</A> connector and <A href="https://support.sap.com/en/product/connectors/nwrfcsdk.html" target="_blank" rel="noopener noreferrer">SAP NW RFC SDK Library</A> make it possible.<BR /> <BR /> For more info check the <A href="https://github.com/SAP/node-rfc/blob/main/doc/usage.md" target="_blank" rel="nofollow noopener noreferrer">node-rfc server documentation</A> and server examples. Example given here is for Node.js platform and it works the same way with Python, using <A href="http://sap.github.io/PyRFC/server.html" target="_blank" rel="nofollow noopener noreferrer">PyRFC</A>.<BR /> <BR /> Background RFC protocol is currently supported for Python and work in progress for Node.js.<BR /> <BR /> Node.js server source code: <A class="Link--primary" href="https://github.com/SAP/node-rfc/blob/main/examples/server-test-blog.mjs" aria-describedby="item-type-10" target="_blank" rel="nofollow noopener noreferrer">server-test-blog.mjs</A><BR /> <BR /> ABAP client source code: <A class="Link--primary" href="https://github.com/SAP/node-rfc/blob/main/examples/zserver_stfc_struct.abap" aria-describedby="item-type-32" target="_blank" rel="nofollow noopener noreferrer">zserver_stfc_struct.abap</A><BR /> <H2 id="toc-hId-963894626">How it works?</H2><BR /> ABAP program can call an ABAP function in Node.js system, over SAP RFC protocol, just like when that function would be in ABAP system. The node-rfc server will route the ABAP RFC call to JavaScript function, registered for serving that ABAP function calls. ABAP function call parameters are automatically transformed to JavaScript and registered JavaScriot function is invoked. After JavaScript function is completed, result is&nbsp; automatically transformed to ABAP format and send back to ABAP client. All standard ABAP RFC call parameters can be used, like ABAP variable (JavaScript variable), ABAP structure (JavaScript "plain" object) or ABAP table (JavaScript array of "plain" objects).<BR /> <BR /> Rather then manually defining ABAP interface the node-rfc server function, the node-rfc can re-use the signature of already existing ABAP function, or empty ABAP function can be created, just to define ABAP function interface for node-rfc server function..<BR /> <BR /> Let try it in real systems, a notebook with Node.js supported LTS release and any new or old ABAP system.<BR /> <H2 id="toc-hId-767381121">ABAP function module signature for Node.js function</H2><BR /> Let use the interface of ABAP function STFC_STRUCTURE, to call JavaScript function which we will create. The STFC_STRUCTURE expects one input structure, IMPORTSTRUCT and returns one variable, the RESPTEXT string and one structure, ECHOSTRUCT. There is also a table parameter RFCTABLE:<BR /> <PRE class="language-abap"><CODE>FUNCTION STFC_STRUCTURE.<BR /> *"----------------------------------------------------------------------<BR /> *"*"Lokale Schnittstelle:<BR /> *" IMPORTING<BR /> *" VALUE(IMPORTSTRUCT) LIKE RFCTEST STRUCTURE RFCTEST<BR /> *" EXPORTING<BR /> *" VALUE(ECHOSTRUCT) LIKE RFCTEST STRUCTURE RFCTEST<BR /> *" VALUE(RESPTEXT) LIKE SY-LISEL<BR /> *" TABLES<BR /> *" RFCTABLE STRUCTURE RFCTEST<BR /> *"----------------------------------------------------------------------</CODE></PRE><BR /> Here is our Node.js function, to be called from ABAP using these parameters:<BR /> <PRE class="language-javascript"><CODE>function my_stfc_structure(request_context, abap_input) {<BR /> // inspect request context<BR /> const attributes = request_context["connection_attributes"];<BR /> console.log(<BR /> "[js] my_stfc_structure context:",<BR /> attributes["sysId"], attributes["client"], attributes["user"], attributes["progName"]);<BR /> console.log("[js] my_stfc_structure input:", abap_input.IMPORTSTRUCT);<BR /> <BR /> // prepare response for ABAP client<BR /> const echostruct = abap_input.IMPORTSTRUCT;<BR /> echostruct.RFCINT1 = 2 * echostruct.RFCINT1;<BR /> echostruct.RFCINT2 = 3 * echostruct.RFCINT2;<BR /> echostruct.RFCINT4 = 4 * echostruct.RFCINT4;<BR /> const abap_output = {<BR /> ECHOSTRUCT: echostruct,<BR /> RESPTEXT: `~~~ Node server here ~~~`,<BR /> };<BR /> console.log("[js] my_stfc_structure response:", abap_output);<BR /> <BR /> // return response data<BR /> return abap_output;<BR /> }</CODE></PRE><BR /> Here is Node.js function call from ABAP client, from ABAP test report:<BR /> <PRE class="language-abap"><CODE>call function 'STFC_STRUCTURE' destination 'NWRFC_SERVER_OS'<BR /> exporting<BR /> importstruct = ls_struct<BR /> importing<BR /> echostruct = ls_struct<BR /> resptext = lv_resp<BR /> tables<BR /> rfctable = lt_table<BR /> exceptions<BR /> communication_failure = 1 message lv_error_message<BR /> system_failure = 2 message lv_error_message.<BR /> </CODE></PRE><BR /> To make this ABAP function call into Node.js work just like standard ABAP function call, following steps shall be done, covered in follow-up sections in detail<BR /> <UL><BR /> <LI>ABAP system: Configure RFC destination for node-rfc server</LI><BR /> <LI>Node.js system: Configure node-rfc server connections to ABAP system</LI><BR /> <LI>Node.js system: Create Node.js function to be called from ABAP and launch the server</LI><BR /> <LI>ABAP system: Call Node.js function</LI><BR /> </UL><BR /> <H2 id="toc-hId-570867616">Configure RFC destination for node-rfc server</H2><BR /> Using transaction SM59 create RFC destination of type TCP/IP connection ("T"), like for example<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/sm59-nwrfc_server_os.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">RFC destination configuration - technical settings</P><BR /> If bgRFC protocol shall be supported by node-rfc server, configure the basXML serializer option here:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/sm59-bgRFC.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">RFC destinatin configuration - bgRFC support</P><BR /> <BR /> <H2 id="toc-hId-374354111">Configure node-rfc server connections for ABAP system</H2><BR /> node-rfc server requires two RFC destinations for ABAP system, configured in sapnwrfc.ini file in Node.js system.<BR /> <BR /> The first destination, "MME", is RFC client destination, the node-rfc can use to call ABAP functions. This client connection is used by node-rfc server to obtain ABAP STFC_STRUCTURE function definition, so that node-rfc server can automatically transform ABAP STFC_STRUCTURE call data to JavaScript and vice versa.<BR /> <BR /> The second destination, "MME_GATEWAY", is RFC server destination, open after server is launched and used for listening on ABAP client requests.<BR /> <BR /> <STRONG>sapnwrfc.ini</STRONG><BR /> <PRE class="language-abap"><CODE>DEST=MME<BR /> USER=demo<BR /> PASSWD=welcome<BR /> ASHOST=system51<BR /> SYSNR=00<BR /> CLIENT=620<BR /> LANG=EN<BR /> TRACE=0<BR /> <BR /> DEST=MME_GATEWAY<BR /> GWSERV=sapgw00<BR /> GWHOST=coevi51<BR /> PROGRAM_ID=RFCSERVER<BR /> REG_COUNT=1</CODE></PRE><BR /> <H3 id="toc-hId-306923325">Start node-rfc server</H3><BR /> After <A href="https://github.com/SAP/node-rfc/blob/main/README.md#requirements" target="_blank" rel="nofollow noopener noreferrer">SAP NW RFC SDK binaries</A> are downloaded and installed on your Node.js system, you can create empty folder and install node-rfc<BR /> <PRE class="language-javascript"><CODE>mkdir server<BR /> cd server<BR /> npm init -y<BR /> npm install node-rfc</CODE></PRE><BR /> Now the first server test can be done, to verify ABAP system connections. Create <STRONG>sapnwrfc.ini</STRONG> file in project root directory and create test script, like:<BR /> <PRE class="language-javascript"><CODE>import {RfcLoggingLevel, Server} from "node-rfc";<BR /> <BR /> // Create server instance, initially inactive<BR /> const server = new Server({<BR /> serverConnection: { dest: "MME_GATEWAY" },<BR /> clientConnection: { dest: "MME" },<BR /> // Server options are optional<BR /> serverOptions: {<BR /> logLevel: RfcLoggingLevel.error,<BR /> // authHandler: authHandler,<BR /> },<BR /> });<BR /> <BR /> (async () =&gt; {<BR /> try {<BR /> // Start the server<BR /> await server.start();<BR /> console.log(<BR /> `[js] Server alive: ${server.alive} client handle: ${server.client_connection}`,<BR /> `server handle: ${server.server_connection}`<BR /> );<BR /> } catch (ex) {<BR /> // Catch errors, if any<BR /> console.error(ex);<BR /> }<BR /> })();<BR /> <BR /> // Close the server after 10 seconds<BR /> let seconds = 10;<BR /> <BR /> const tick = setInterval(() =&gt; {<BR /> console.log("tick", --seconds);<BR /> if (seconds &lt;= 0) {<BR /> server.stop(() =&gt; {<BR /> clearInterval(tick);<BR /> console.log("bye!");<BR /> });<BR /> }<BR /> }, 1000);<BR /> </CODE></PRE><BR /> Now open again the NWRFC_SERVER_OS RFC destination using SM59 transaction and find "Connection Test" button<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/sm59-connection-test.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">RFC destination - connection test</P><BR /> Start your test script in Node.js system and after server alive message press the "Connection Test" button. When RFC connection with ABAP system is working, the output looks like this:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/sm59-connection-test-output.png" height="278" width="517" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">RFC destination connection test output</P><BR /> Now when RFC connectivity is working let create Node.js function and call it from ABAP.<BR /> <H2 id="toc-hId--18672899">Create Node.js function to be called from ABAP and launch the server</H2><BR /> Let add "my_stfc_structure" JavaScript server function, to receive ABAP calls of STFC_STRUCTURE function in Node.js system. Two additions are required in our test script, the server function implementation and registration.<BR /> <BR /> Server function requires nothing special for node-rfc server, it shall implement only "plain" logic to calculate the response for ABAP client. Also promise can be returned.<BR /> <BR /> The first parameter is request_context, just in case the function implementation shall consider it. The second parameter is JavaScript object with ABAP parameters, as defined by ABAP STFC_STRUCTURE function signature.<BR /> <PRE class="language-javascript"><CODE>// Server function<BR /> function my_stfc_structure(request_context, abap_input) {<BR /> const connection_attributes = request_context["connection_attributes"];<BR /> console.log(<BR /> "[js] my_stfc_structure context:",<BR /> connection_attributes["sysId"],<BR /> connection_attributes["client"],<BR /> connection_attributes["user"],<BR /> connection_attributes["progName"]<BR /> );<BR /> console.log("[js] my_stfc_structure input:", abap_input.IMPORTSTRUCT);<BR /> const echostruct = abap_input.IMPORTSTRUCT;<BR /> echostruct.RFCINT1 = 2 * echostruct.RFCINT1;<BR /> echostruct.RFCINT2 = 3 * echostruct.RFCINT2;<BR /> echostruct.RFCINT4 = 4 * echostruct.RFCINT4;<BR /> const abap_output = {<BR /> ECHOSTRUCT: echostruct,<BR /> RESPTEXT: `~~~ Node server here ~~~`,<BR /> };<BR /> <BR /> console.log("[js] my_stfc_structure response:", abap_output);<BR /> return abap_output;<BR /> }<BR /> </CODE></PRE><BR /> The server function is registered using node-rfc server "addFuncion" method, telling the server to route ABAP STFC_STRUCTURE function calls to JavaScript function "my_stfc_structure":<BR /> <PRE class="language-javascript"><CODE> server.addFunction("STFC_STRUCTURE", my_stfc_structure);</CODE></PRE><BR /> ABAP data transformations to/from JavaScript are done by node-rfc server automatically.<BR /> <BR /> Our test script is now ready and the node-rfc server can be started, to serve ABAP client calls:<BR /> <PRE class="language-javascript"><CODE>import { RfcLoggingLevel, Server } from "node-rfc";<BR /> <BR /> // Create server instance, initially inactive<BR /> const server = new Server({<BR /> serverConnection: { dest: "MME_GATEWAY" },<BR /> clientConnection: { dest: "MME" },<BR /> // Server options are optional<BR /> serverOptions: {<BR /> logLevel: RfcLoggingLevel.error,<BR /> // authHandler: authHandler,<BR /> },<BR /> });<BR /> <BR /> // Server function<BR /> function my_stfc_structure(request_context, abap_input) {<BR /> const connection_attributes = request_context["connection_attributes"];<BR /> console.log(<BR /> "[js] my_stfc_structure context:",<BR /> connection_attributes["sysId"],<BR /> connection_attributes["client"],<BR /> connection_attributes["user"],<BR /> connection_attributes["progName"]<BR /> );<BR /> console.log("[js] my_stfc_structure input:", abap_input.IMPORTSTRUCT);<BR /> const echostruct = abap_input.IMPORTSTRUCT;<BR /> echostruct.RFCINT1 = 2 * echostruct.RFCINT1;<BR /> echostruct.RFCINT2 = 3 * echostruct.RFCINT2;<BR /> echostruct.RFCINT4 = 4 * echostruct.RFCINT4;<BR /> const abap_output = {<BR /> ECHOSTRUCT: echostruct,<BR /> RESPTEXT: `~~~ Node server here ~~~`,<BR /> };<BR /> <BR /> console.log("[js] my_stfc_structure response:", abap_output);<BR /> return abap_output;<BR /> }<BR /> <BR /> (async () =&gt; {<BR /> try {<BR /> // Register server function<BR /> server.addFunction("STFC_STRUCTURE", my_stfc_structure);<BR /> console.log(<BR /> `[js] Node.js function '${my_stfc_structure.name}'`,<BR /> "registered as ABAP 'STFC_STRUCTURE' function"<BR /> );<BR /> // Start the server<BR /> await server.start();<BR /> console.log(<BR /> `[js] Server alive: ${server.alive} client handle: ${server.client_connection}`,<BR /> `server handle: ${server.server_connection}`<BR /> );<BR /> } catch (ex) {<BR /> // Catch errors, if any<BR /> console.error(ex);<BR /> }<BR /> })();<BR /> <BR /> // Close the server after 10 seconds<BR /> let seconds = 10;<BR /> <BR /> const tick = setInterval(() =&gt; {<BR /> console.log("tick", --seconds);<BR /> if (seconds &lt;= 0) {<BR /> server.stop(() =&gt; {<BR /> clearInterval(tick);<BR /> console.log("bye!");<BR /> });<BR /> }<BR /> }, 1000);<BR /> </CODE></PRE><BR /> When test script is started in Node.js system and ABAP test report calls STFC_STRUCTURE function in Node.js system, the test script output looks like:<BR /> <PRE class="language-abap"><CODE>ts-node ci/test/server-test.ts (py3.11.4) ✘ 1 main ◼<BR /> [js] Node.js function 'my_stfc_structure' registered as ABAP 'STFC_STRUCTURE' function<BR /> [js] Server alive: false client handle: 5554800128 server handle: 0<BR /> tick 9<BR /> tick 8<BR /> [js] my_stfc_structure context: MME 620 D037732 ZSERVER_STFC_STRUCT<BR /> [js] my_stfc_structure input: {<BR /> RFCFLOAT: 0,<BR /> RFCCHAR1: '',<BR /> RFCINT2: 2,<BR /> RFCINT1: 1,<BR /> RFCCHAR4: '',<BR /> RFCINT4: 4,<BR /> RFCHEX3: &lt;Buffer 00 00 00&gt;,<BR /> RFCCHAR2: '',<BR /> RFCTIME: '000000',<BR /> RFCDATE: '00000000',<BR /> RFCDATA1: '',<BR /> RFCDATA2: ''<BR /> }<BR /> [js] my_stfc_structure response: {<BR /> ECHOSTRUCT: {<BR /> RFCFLOAT: 0,<BR /> RFCCHAR1: '',<BR /> RFCINT2: 6,<BR /> RFCINT1: 2,<BR /> RFCCHAR4: '',<BR /> RFCINT4: 16,<BR /> RFCHEX3: &lt;Buffer 00 00 00&gt;,<BR /> RFCCHAR2: '',<BR /> RFCTIME: '000000',<BR /> RFCDATE: '00000000',<BR /> RFCDATA1: '',<BR /> RFCDATA2: ''<BR /> },<BR /> RESPTEXT: '~~~ Node server here ~~~'<BR /> }<BR /> tick 7<BR /> tick 6<BR /> tick 5<BR /> ^C</CODE></PRE><BR /> <H2 id="toc-hId--215186404">Calling Node.js function from ABAP</H2><BR /> Here is ABAP test report for calling Node.js function, used in this example<BR /> <PRE class="language-abap"><CODE>*&amp;---------------------------------------------------------------------*<BR /> *&amp; Report ZSERVER_STFC_STRUCT<BR /> *&amp;---------------------------------------------------------------------*<BR /> *&amp;<BR /> *&amp;---------------------------------------------------------------------*<BR /> report zserver_stfc_struct.<BR /> <BR /> data lv_echo like sy-lisel.<BR /> data lv_resp like sy-lisel.<BR /> <BR /> data ls_struct like rfctest.<BR /> data lt_table like table of rfctest.<BR /> <BR /> data lv_error_message type char512.<BR /> <BR /> ls_struct-rfcint1 = 1.<BR /> ls_struct-rfcint2 = 2.<BR /> ls_struct-rfcint4 = 4.<BR /> <BR /> insert ls_struct into table lt_table.<BR /> call function 'STFC_STRUCTURE' destination 'NWRFC_SERVER_OS'<BR /> exporting<BR /> importstruct = ls_struct<BR /> importing<BR /> echostruct = ls_struct<BR /> resptext = lv_resp<BR /> tables<BR /> rfctable = lt_table<BR /> exceptions<BR /> communication_failure = 1 message lv_error_message<BR /> system_failure = 2 message lv_error_message.<BR /> <BR /> if sy-subrc eq 0.<BR /> write: / 'rfcint1:', ls_struct-rfcint1.<BR /> write: / 'rfcint2:', ls_struct-rfcint2.<BR /> write: / 'rfcint4:', ls_struct-rfcint4.<BR /> write: / 'resptext:', lv_resp.<BR /> else.<BR /> write: 'subrc :', sy-subrc.<BR /> write: / 'msgid :', sy-msgid, sy-msgty, sy-msgno.<BR /> write: / 'msgv1-4:', sy-msgv1, sy-msgv2, sy-msgv3, sy-msgv4.<BR /> write: / 'message:', lv_error_message.<BR /> exit.<BR /> endif.</CODE></PRE><BR /> When node-rfc server is running and this ABAP report started, the output looks like:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/ABAP-report-output.png" height="312" width="539" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Node.js server call output</P><BR /> <BR /> <H2 id="toc-hId--411699909"><STRONG>Error Handling</STRONG></H2><BR /> In case of error, the server function shall raise exception message and error message will be returned to ABAP, with RFC_EXTERNAL_FAILURE error code.<BR /> <PRE class="language-abap"><CODE> throw new Error("my_stfc_function error");<BR /> <BR /> console.log("[js] my_stfc_structure response:", abap_output);<BR /> return abap_output;<BR /> }</CODE></PRE><BR /> ABAP report output<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/Screenshot-2023-08-25-at-18.22.12.png" height="298" width="505" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">ABAP test report - error</P><BR /> <BR /> <H2 id="toc-hId--608213414">Logging</H2><BR /> When activated, the log is saved in local file: _noderfc.log and above mentioned error looks like:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/error-log.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Error log</P><BR /> Enjoy calling Node.js function from ABAP <span class="lia-unicode-emoji" title=":slightly_smiling_face:">🙂</span><BR /> <BR /> &nbsp; 2023-08-25T16:45:09+02:00 https://community.sap.com/t5/technology-blogs-by-sap/abap-rfc-connectivity-from-btp-node-js-buildpack-and-kyma/ba-p/13573993 ABAP RFC connectivity from BTP Node.JS buildpack and Kyma 2023-10-26T16:14:54+02:00 Srdjan https://community.sap.com/t5/user/viewprofilepage/user-id/174007 ABAP RFC connectivity from BTP to ABAP systems is supported by <A href="https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/cloud-connector" target="_blank" rel="noopener noreferrer">SAP Cloud Connector</A>, for Java runtime only. This blog describes the RFC connectivity configuration for BTP Node.JS runtime, so that Node.JS BTP applications can consume ABAP RFCs, as described in <EM>Deployment options </EM>section of <A href="https://blogs.sap.com/2023/10/12/powerful-web-applications-with-old-and-new-abap-systems" target="_blank" rel="noopener noreferrer">Powerful web applications with old and new ABAP systems</A> and related blogs.<BR /> <BR /> Our "hello world" example is BTP Node.JS buildpack, with <A href="https://expressjs.com/" target="_blank" rel="nofollow noopener noreferrer">Express</A> server, <A href="https://github.com/SAP/node-rfc" target="_blank" rel="nofollow noopener noreferrer">SAP/node-rfc</A> and <A href="https://support.sap.com/en/product/connectors/nwrfcsdk.html" target="_blank" rel="noopener noreferrer">SAP NW RFC SDK</A>.<BR /> <BR /> The example source code: <A href="https://github.com/SAP-samples/node-rfc-samples/tree/main/integration/noderfc_btp" target="_blank" rel="nofollow noopener noreferrer">SAP-samples/node-rfc-samples//integration/noderfc_btp</A> can be deployed on BTP or tested locally inside <A href="https://github.com/SAP/fundamental-tools/blob/main/docker/btp-cflinuxfs4.Dockerfile" target="_blank" rel="nofollow noopener noreferrer">SAP/fundamental-tools/docker/btp_cflinuxfs4.Dockerfile</A> docker container.<BR /> <BR /> ABAP RFC connectivity from Node.JS on Kyma works practically out of the box, using <A href="https://github.com/SAP/node-rfc" target="_blank" rel="nofollow noopener noreferrer">SAP/node-rfc</A> and <A href="https://support.sap.com/en/product/connectors/nwrfcsdk.html" target="_blank" rel="noopener noreferrer">SAP NW RFC SDK</A> inside docker container. Try <A href="http://SAP/fundamental-tools/blob/main/docker/cflinuxfs4.Dockerfile" target="_blank" rel="nofollow noopener noreferrer">SAP/fundamental-tools/docker/cflinuxfs4.Dockerfile</A> for example.<BR /> <H2 id="toc-hId-963931172">SAP NW RFC SDK on BTP</H2><BR /> ABAP RFC connectivity from Node.JS is provided by <A href="https://github.com/SAP/node-rfc" target="_blank" rel="nofollow noopener noreferrer">SAP/node-rfc</A> open source, which provides interface to SAP proprietary SAP NW RFC SDK<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/nwrfcsdk-2.png" height="139" width="165" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">SAP NW RFC SDK</P><BR /> SAP NW RFC SDK is <STRONG>not included</STRONG> in <A href="https://github.com/sap/node-rfc" target="_blank" rel="nofollow noopener noreferrer">SAP/node-rfc</A> because of licensing and SAP Support Portal is the only allowed public distribution channel for SAP NW RFC SDK.<BR /> <BR /> Shared SO libraries are required in runtime and must be registered at operating system level, using LD_LIBRARY_PATH env variable on Linux systems for example. Include files and shared libraries are both required for <A href="https://github.com/sap/node-rfc" target="_blank" rel="nofollow noopener noreferrer">SAP/node-rfc</A> build and re-build. The node-rfc rebuild can be triggered during BTP deployment, just like for other native Node.JS modules.<BR /> <BR /> Express and SAP/node-rfc are standard NPM packages and BTP deployment is straightforward.<BR /> <H2 id="toc-hId-767417667">Preparation</H2><BR /> We use this <A href="https://github.com/SAP/fundamental-tools/blob/main/docker/btp-cflinuxfs4.Dockerfile" target="_blank" rel="nofollow noopener noreferrer">btp_cflinuxfs4 docker container</A> and standard buildpack structure, with application in <EM>app</EM> folder. To make SAP NW RFC SDK available for <A href="https://github.com/sap/node-rfc" target="_blank" rel="nofollow noopener noreferrer">SAP/node-rfc</A> in cloud application, it shall be copied to app root folder for example:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/Screenshot-2023-12-06-at-11.54.27.png" height="124" width="186" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Buildpack</P><BR /> During deployment, native NPM modules like node-rfc may be or must be rebuilt. The re-build process requires SAP NW RFC SDK includes and binaries and <EM>SAPNWRFC_HOME_CLOUD </EM>environment vaiable shell therefore point to SAP NW RFC SDK root folder, just like SAPNWRFC_HOME in on-premise case.<BR /> <BR /> For run-time enablement, the <EM>LD_LIBRARY_PATH</EM> env variable shall point to RFC SDK "lib" folder, like in&nbsp;<A href="https://github.com/SAP-samples/node-rfc-samples/blob/main/integration/noderfc_with_nwrfcsdk/buildpack/manifest.yaml#L7" target="_blank" rel="nofollow noopener noreferrer">manifest.yaml:</A><BR /> <PRE class="language-python"><CODE>---<BR /> applications:<BR /> - name: rfcapp<BR /> stack: cflinuxfs4<BR /> env:<BR /> SAPNWRFC_HOME_CLOUD: /tmp/app/nwrfcsdk<BR /> LD_LIBRARY_PATH: /home/vcap/app/nwrfcsdk/lib</CODE></PRE><BR /> That's all, we are ready for testing.<BR /> <H2 id="toc-hId-570904162">Local test</H2><BR /> <PRE class="language-python"><CODE>$ cd buildpack/app<BR /> $ export SAPNWRFC_HOME=`pwd`/nwrfcsdk<BR /> $ export LD_LIBRARY_PATH=$SAPNWRFC_HOME/lib<BR /> $ npm install<BR /> $ node .<BR /> <BR /> node .<BR /> HOME<BR /> /home/www-admin<BR /> <BR /> SAPNWRFC_HOME<BR /> /home/www-admin/src/sap/node-rfc-samples/integration/noderfc_with_nwrfcsdk/buildpack/app/nwrfcsdk<BR /> <BR /> SAPNWRFC_HOME files:<BR /> ["include","lib","package.json"]<BR /> <BR /> LD_LIBRARY_PATH<BR /> <BR /> <BR /> node-rfc<BR /> {<BR /> "platform": {<BR /> "name": "linux",<BR /> "arch": "x64",<BR /> "release": "6.4.16-linuxkit"<BR /> },<BR /> "env": {<BR /> "SAPNWRFC_HOME": "/home/www-admin/src/sap/node-rfc-samples/integration/noderfc_with_nwrfcsdk/buildpack/app/nwrfcsdk",<BR /> "RFC_INI": ""<BR /> },<BR /> "versions": {<BR /> "node": "18.18.2",<BR /> "acorn": "8.10.0",<BR /> "ada": "2.6.0",<BR /> "ares": "1.19.1",<BR /> "brotli": "1.0.9",<BR /> "cldr": "43.1",<BR /> "icu": "73.2",<BR /> "llhttp": "6.0.11",<BR /> "modules": "108",<BR /> "napi": "9",<BR /> "nghttp2": "1.57.0",<BR /> "nghttp3": "0.7.0",<BR /> "ngtcp2": "0.8.1",<BR /> "openssl": "3.0.10+quic",<BR /> "simdutf": "3.2.14",<BR /> "tz": "2023c",<BR /> "undici": "5.26.3",<BR /> "unicode": "15.0",<BR /> "uv": "1.44.2",<BR /> "uvwasi": "0.0.18",<BR /> "v8": "10.2.154.26-node.26",<BR /> "zlib": "1.2.13.1-motley"<BR /> },<BR /> "noderfc": {<BR /> "version": "3.3.0",<BR /> "nwrfcsdk": {<BR /> "major": 7500,<BR /> "minor": 0,<BR /> "patchLevel": 12<BR /> }<BR /> }<BR /> }</CODE></PRE><BR /> <H3 id="toc-hId-503473376">BTP Deployment</H3><BR /> When all works fine, let deploy<BR /> <PRE class="language-abap"><CODE>$ cd buildpack<BR /> $ cf push<BR /> Pushing app rfcapp to ...<BR /> Uploading files...<BR /> Instances starting....<BR /> Instances starting...<BR /> <BR /> name: rfcapp<BR /> requested state: started<BR /> routes: rfcapp.cfapps.eu10.hana.ondemand.com<BR /> last uploaded: Thu 26 Oct 15:46:54 CEST 2023<BR /> stack: cflinuxfs4<BR /> buildpacks: <BR /> name version detect output buildpack name<BR /> <A href="https://github.com/cloudfoundry/nodejs-buildpack#v1.8.18" target="test_blank" rel="nofollow noopener noreferrer">https://github.com/cloudfoundry/nodejs-buildpack#v1.8.18</A> 1.8.18 nodejs nodejs<BR /> <BR /> type: web<BR /> sidecars: <BR /> instances: 1/1<BR /> memory usage: 128M<BR /> start command: npm run start:btp<BR /> state since cpu memory disk logging details<BR /> #0 running 2023-10-26T13:47:09Z 0.0% 54.9M of 128M 231.8M of 1G 0/s of unlimited </CODE></PRE><BR /> The app test route <A href="https://rfcapp.cfapps.eu10.hana.ondemand.com/" target="_blank" rel="nofollow noopener noreferrer"><STRONG></STRONG></A><A href="https://rfcapp.cfapps.eu10.hana.ondemand.com" target="test_blank" rel="nofollow noopener noreferrer">https://rfcapp.cfapps.eu10.hana.ondemand.com</A>/ shows the same result as on premise test:<BR /> <PRE class="language-abap"><CODE>HOME /home/vcap/app SAPNWRFC_HOME /home/vcap/app/node_modules/nwrfcsdk<BR /> SAPNWRFC_HOME files: ["include","lib","package.json"]<BR /> LD_LIBRARY_PATH /home/vcap/app/node_modules/nwrfcsdk/lib<BR /> node-rfc { "platform": { "name": "linux", "arch": "x64", "release": "6.2.0-33-generic" }, "env": { "SAPNWRFC_HOME": "/home/vcap/app/node_modules/nwrfcsdk", "RFC_INI": "" }, "versions": { "node": "18.18.2", "acorn": "8.10.0", "ada": "2.6.0", "ares": "1.19.1", "brotli": "1.0.9", "cldr": "43.1", "icu": "73.2", "llhttp": "6.0.11", "modules": "108", "napi": "9", "nghttp2": "1.57.0", "nghttp3": "0.7.0", "ngtcp2": "0.8.1", "openssl": "3.0.10+quic", "simdutf": "3.2.14", "tz": "2023c", "undici": "5.26.3", "unicode": "15.0", "uv": "1.44.2", "uvwasi": "0.0.18", "v8": "10.2.154.26-node.26", "zlib": "1.2.13.1-motley" }, "noderfc": { "version": "3.3.0", "nwrfcsdk": { "major": 7500, "minor": 0, "patchLevel": 12 } } }</CODE></PRE><BR /> <H2 id="toc-hId-177877152">Connectivity</H2><BR /> With RFC connectivity enabled in Node.JS on BTP, WS-RFC connection parameters and SAP Business Connector or Cloud Connector can be used for RFC connections to ABAP systems.<BR /> <BR /> &nbsp; 2023-10-26T16:14:54+02:00 https://community.sap.com/t5/technology-blogs-by-members/securing-external-rfc-connections-including-certificate-based/ba-p/13575027 Securing external RFC connections, including certificate-based authentication 2023-12-07T09:18:50+01:00 L_Skorwider https://community.sap.com/t5/user/viewprofilepage/user-id/172246 In today's world of cyber-attacks and data leaks, security and encryption should be an absolute priority for any IT organisation. However, experience shows that this is not always the case. Mechanisms that bring security are still often seen as making work difficult and challenging to implement. The fact that a program was configured years before and there was never a problem is used as an excuse not to make changes. This is a very incorrect approach that can have serious consequences.<BR /> <BR /> In this post, I will cover a topic perhaps quite niche for the SAP Basis administrator - securing connections from external non-SAP programs. An aspect that is often overlooked due to a gap in accountability. On the one hand, this is sometimes seen as outside the Basis scope. On the other hand, programs are sometimes configured by third party vendors not necessarily interested in the security of our system. I will try to show what we, as Basis administrators, can do to make the connection more secure.<BR /> <H1 id="toc-hId-834899173">Scope of consideration</H1><BR /> In this post I will try to consider what mechanisms we can use to make an external connection secure. Of course, SNC/SSL-based encryption will be the focus as usual, but I will not limit myself to this technical aspect alone. As usual, I will also touch on topics that are on the borderline of responsibilities or even outside the typical scope of Basis, but important for understanding how the various mechanisms work.<BR /> <BR /> I will discuss the topics of encryption, authentication using an SSL certificate, level of trust in a foreign CA, permissions, limiting network traffic. I will base my analysis on example programs from the <A href="https://support.sap.com/en/product/connectors/nwrfcsdk.html" target="_blank" rel="noopener noreferrer">SAP NetWeaver RFC SDK</A>. I originally wanted to write my own simple program, but as Basis administrators we usually secure existing software and connections, so this is a more representative example.<BR /> <H1 id="toc-hId-638385668">Environment preparation</H1><BR /> <H2 id="toc-hId-570954882">SAP server side</H2><BR /> My test environment is <A href="https://blogs.sap.com/2023/07/31/abap-platform-trial-1909-available-now/" target="_blank" rel="noopener noreferrer">ABAP Platform Trial 1909</A>, based on S/4HANA 1909. The system is not the youngest, nor is it the oldest, but in the field of RFC connection security, not that much has changed over the years. So most of the insights will be valid for both older and younger systems.<BR /> <BR /> The system has already been prepped for SNC and certificate-based authentication. I described this in my previous post "<A href="https://blogs.sap.com/2023/11/23/sap-gui-single-sign-on-based-on-ssl-certificates-and-snc/" target="_blank" rel="noopener noreferrer">SAP-GUI Single Sign-On based on SSL certificates and SNC</A>", so I won't repeat that part.<BR /> <H2 id="toc-hId-374441377">Client side</H2><BR /> For the purpose of presenting the client program, I prepared a completely fresh Debian Linux system version 12. The <EM>rfcuser</EM> user was also created, in the context of which we will run the program that connects to the SAP server. Of course, you can use another Linux distribution as well, or even Windows, and the results will be similar.<BR /> <H1 id="toc-hId-48845153">SAP NetWeaver RFC SDK</H1><BR /> SAP Note 2573790 describes where to get the library and briefly describes the installation process. I assume you can download it yourself from the Software Download Center, and I will describe the simplest installation method in a moment. I get two files, which I decompress in the <EM>rfcuser</EM> home directory.<BR /> <PRE><CODE>rfcuser@sandboxn100:~$ <STRONG>unzip nwrfc750P_12-70002752.zip</STRONG><BR /> <BR /> Archive: nwrfc750P_12-70002752.zip<BR /> <BR /> creating: nwrfcsdk/<BR /> <BR /> creating: nwrfcsdk/bin/<BR /> <BR /> inflating: nwrfcsdk/bin/rfcexec<BR /> <BR /> inflating: nwrfcsdk/bin/startrfc</CODE></PRE><BR /> [...]<BR /> <PRE><CODE>inflating: nwrfcsdk/lib/libsapnwrfc.so<BR /> <BR /> inflating: nwrfcsdk/lib/libsapucum.so<BR /> <BR /> inflating: SIGNATURE.SMF<BR /> <BR /> rfcuser@sandboxn100:~$ <STRONG>unzip nwrfc750P12HF_2-70002752.zip</STRONG><BR /> <BR /> Archive: nwrfc750P12HF_2-70002752.zip<BR /> <BR /> inflating: libsapnwrfc.so<BR /> <BR /> rfcuser@sandboxn100:~$ <STRONG>mv libsapnwrfc.so nwrfcsdk/lib/</STRONG></CODE></PRE><BR /> All files are located in <EM>nwrfcsdk</EM> folder. Next step is adding the folder to <EM>LD_LIBRARY_PATH</EM> environment variable. I can do this for current session, but to make this permanent, I add this to <EM>.profile</EM> file located in the user's home directory.<BR /> <PRE><CODE>export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/nwrfcsdk/lib</CODE></PRE><BR /> <H1 id="toc-hId--147668352">SAP user</H1><BR /> I plan to establish a connection from an external program to my SAP system to perform some operations. It is easy to guess that I will need a user on the SAP system side to do this. So I'm creating an RFC user that the external program will use for operations on the system. I give it the top-secret password <EM>secure123</EM>, just for the purpose of this presentation, to keep things simple.<BR /> <BR /> In addition to filling in basic user data, I set up the type to <EM>system</EM> or <EM>communication</EM>. In this case, it doesn't matter much. I leave the rest of the data default, including the lack of authorizations, because I'll come back to that in the next step.<BR /> <H1 id="toc-hId--344181857">The first, unsecured connection</H1><BR /> Together with the SDK library, we get two sample programs - <EM>rfcexec</EM> and <EM>startrfc</EM>. <EM>Rfcexec</EM> connects to the SAP gateway and waits for incoming commands from the SAP system. I leave it for another occasion for now and will focus on <EM>startrfc</EM>.<BR /> <BR /> The program connects to SAP and execute one of two function modules, related to EDI or display system information. In fact, I will focus on the last function today. The <EM>-i</EM> switch is responsible for calling it.<BR /> <BR /> Let's call the program:<BR /> <PRE><CODE>rfcuser@sandboxn100:~/nwrfcsdk/bin$ ./startrfc -h sandbox -s 00 -u rfcuser -p secure123 -c 001 -i<BR /> Error: No RFC authorization for function module RFCPING.</CODE></PRE><BR /> <EM>Sandbox</EM> is my SAP server hostname <EM>00</EM> is SAP instance number. <EM>001</EM> is a productive client.<BR /> <BR /> Error is expected. In general connection is successful, because program reached checking authorization phase.<BR /> <H1 id="toc-hId--540695362">The principle of least privilege</H1><BR /> Indisputably, the principle of least privilege is one of the most important elements of security and an absolute must when it comes to external connections. Keep in mind that a system is only as secure as its weakest component. Even if you secure your SAP system perfectly, an intrusion into a server independent of you that has rights to connect to SAP with a high level of privilege could result in data leakage or even damage to the system. So you should keep the level of RFC user privileges at the minimum level needed to operate. In fact, this should obviously apply to all users. However, for technical users, this rule is more often ignored for some reason. Do we trust programs more than people?<BR /> <BR /> That's why I didn't give the <EM>RFCUSER</EM>&nbsp;any authorization at the beginning, and now I will build it from scratch. I check what the <EM>SU53</EM> transaction reports for this user by selecting <EM>Authorization Values</EM> / <EM>Other User</EM> from the menu.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/su53-rfcuser.png" /></P><BR /> Apparently, the system first checked whether the user had access to the <EM>RFCPING</EM> function module. Since access was not explicitly granted, so the permissions for the entire <EM>SYST</EM> function group were also checked. Since I am very strict about permissions, I will build a role with minimal privileges in the <EM>PFCG</EM> tranaction.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/pfcg-rfc-user-role.png" /></P><BR /> I added this role to RFCUSER and repeated the connection test.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/nwrfcsdk/bin$ <STRONG>./startrfc -h sandbox -s 00 -u rfcuser -p secure123 -c 001 -i</STRONG><BR /> SAP System ID: A4H<BR /> SAP System Number: 00<BR /> Partner Host: vhcala4hci<BR /> Own Host: sandboxn100<BR /> Partner System Release: 754<BR /> Partner Kernel Release: 777<BR /> Own Release: 753<BR /> Partner Codepage: 4103<BR /> Own Codepage: 4103<BR /> User: RFCUSER<BR /> Client: 001<BR /> Language: E<BR /> </CODE></PRE><BR /> This time the connection is fully successful and I get system information. Authorization is sufficient.<BR /> <H1 id="toc-hId--737208867">Certification authority</H1><BR /> At this point it is worth saying a few words about how my system is configured. This is, in fact, already described in my <A href="https://blogs.sap.com/2023/11/23/sap-gui-single-sign-on-based-on-ssl-certificates-and-snc/" target="_blank" rel="noopener noreferrer">previous post</A>, but it doesn't do any harm to remind you of the basic information. The main certificate authority <EM>(OU=Security)</EM> signed the certificates of intermediate authorities - for servers <EM>(OU=Servers)</EM> and for users <EM>(OU=Users)</EM>. The SAP server certificate was issued by the first one.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/strust-certificates.png" /></P><BR /> It's clear that the simplest solution would be to issue a certificate by an existing certification authority, but that would simplify our considerations a bit too much. Instead, I will assume that the certificate was issued by a completely independent group of certification authorities. So I will add three new to the existing ones, marked in blue in the diagram.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/ca-structure.png" /></P><BR /> I won't focus on details, because you can go through this proces in my previous post, but let's go to the process of CAs creation and issuing RFCUSER's certificate. In practice, SAP administrators are usually not responsible for this part, so if you are not interested in issuing certificates, you can skip without hesitation to the next chapter.<BR /> <BR /> Root CA key creation:<BR /> <PRE><CODE>openssl genrsa -out AnotherRootCA/anotherca.key.pem 4096</CODE></PRE><BR /> Certificate generation:<BR /> <PRE><CODE>openssl req -x509 -sha256 -new -nodes -key AnotherRootCA/anotherca.key.pem -days 3650 -out AnotherRootCA/anotherca.cert.pem<BR /> You are about to be asked to enter information that will be incorporated<BR /> into your certificate request.<BR /> What you are about to enter is what is called a Distinguished Name or a DN.<BR /> There are quite a few fields but you can leave some blank<BR /> For some fields there will be a default value,<BR /> If you enter '.', the field will be left blank.<BR /> -----<BR /> Country Name (2 letter code) [AU]:PL<BR /> State or Province Name (full name) [Some-State]:kuj-pom<BR /> Locality Name (eg, city) []:<BR /> Organization Name (eg, company) [Internet Widgits Pty Ltd]:AnotherCompany<BR /> Organizational Unit Name (eg, section) []:Trustworthy<BR /> Common Name (e.g. server FQDN or YOUR name) []:Another Root CA<BR /> Email Address []:</CODE></PRE><BR /> Intermediate CA key:<BR /> <PRE><CODE>openssl genrsa -out intermediateAppsCA/interApps.key.pem 4096</CODE></PRE><BR /> Certificate signing request:<BR /> <PRE><CODE>openssl req -key intermediateAppsCA/interApps.key.pem -new -sha256 -out intermediateAppsCA/interApps.csr.pem<BR /> You are about to be asked to enter information that will be incorporated<BR /> into your certificate request.<BR /> What you are about to enter is what is called a Distinguished Name or a DN.<BR /> There are quite a few fields but you can leave some blank<BR /> For some fields there will be a default value,<BR /> If you enter '.', the field will be left blank.<BR /> -----<BR /> Country Name (2 letter code) [AU]:PL<BR /> State or Province Name (full name) [Some-State]:kuj-pom<BR /> Locality Name (eg, city) []:<BR /> Organization Name (eg, company) [Internet Widgits Pty Ltd]:AnotherCompany<BR /> Organizational Unit Name (eg, section) []:Apps<BR /> Common Name (e.g. server FQDN or YOUR name) []:Intermediate Apps CA<BR /> Email Address []:<BR /> <BR /> Please enter the following 'extra' attributes<BR /> to be sent with your certificate request<BR /> A challenge password []:*******<BR /> An optional company name []:</CODE></PRE><BR /> Certificate signature by the new root CA:<BR /> <PRE><CODE>openssl x509 -req -in intermediateAppsCA/interApps.csr.pem -days 3650 -CA AnotherRootCA/anotherca.cert.pem -CAkey AnotherRootCA/anotherca.key.pem -CAcreateserial -out intermediateAppsCA/interApps.cert.pem<BR /> Certificate request self-signature ok<BR /> subject=C = PL, ST = kuj-pom, O = AnotherCompany, OU = Apps, CN = Intermediate Apps CA</CODE></PRE><BR /> RFCUSER key creation:<BR /> <PRE><CODE>openssl genrsa -out intermediateAppsCA/rfcuser.key.pem 4096</CODE></PRE><BR /> Certificate signing request:<BR /> <PRE><CODE>openssl req -key intermediateAppsCA/rfcuser.key.pem -new -sha256 -out intermediateAppsCA/rfcuser.csr.pem<BR /> You are about to be asked to enter information that will be incorporated<BR /> into your certificate request.<BR /> What you are about to enter is what is called a Distinguished Name or a DN.<BR /> There are quite a few fields but you can leave some blank<BR /> For some fields there will be a default value,<BR /> If you enter '.', the field will be left blank.<BR /> -----<BR /> Country Name (2 letter code) [AU]:PL<BR /> State or Province Name (full name) [Some-State]:kuj-pom<BR /> Locality Name (eg, city) []:<BR /> Organization Name (eg, company) [Internet Widgits Pty Ltd]:AnotherCompany<BR /> Organizational Unit Name (eg, section) []:<BR /> Common Name (e.g. server FQDN or YOUR name) []:RFCUSER<BR /> Email Address []:<BR /> <BR /> Please enter the following 'extra' attributes<BR /> to be sent with your certificate request<BR /> A challenge password []:********<BR /> An optional company name []:</CODE></PRE><BR /> <EM>Client.cnf</EM> for client certificates:<BR /> <PRE><CODE>nsCertType = client<BR /> extendedKeyUsage = clientAuth</CODE></PRE><BR /> Certificate signing:<BR /> <PRE><CODE>openssl x509 -req -days 365 -in intermediateAppsCA/rfcuser.csr.pem -sha256 -CA intermediateAppsCA/interApps.cert.pem -CAkey intermediateAppsCA/interApps.key.pem -CAcreateserial -out intermediateAppsCA/rfcuser.crt.pem -extfile intermediateAppsCA/client.cnf<BR /> Certificate request self-signature ok<BR /> subject=C = PL, ST = kuj-pom, O = AnotherCompany, CN = RFCUSER</CODE></PRE><BR /> Export certificate to PKCS12 format:<BR /> <PRE><CODE>openssl pkcs12 -export -inkey intermediateAppsCA/rfcuser.key.pem -in intermediateAppsCA/rfcuser.crt.pem -certfile AnotherRootCA/anotherca.cert.pem -certfile intermediateAppsCA/interApps.cert.pem -out rfcuser.p12<BR /> Enter Export Password:<BR /> Verifying - Enter Export Password:<BR /> exportpassword123</CODE></PRE><BR /> As a result I got several keys and certificates, including the most important rfcuser.p12 file, which contains user's private key and certificate with the trust chain. The file is protected with <EM>exportpassword123</EM> password. In real life scenarion this file you'll receive from your certification team.<BR /> <H1 id="toc-hId--933722372">Enforcing RFC encryption on system level</H1><BR /> Ok, I know that forcing encrypted connections is not necessary for my connection to be encrypted. However, I will do it to show if the encryption works or not. Nevertheless, if you are ready to disable unsafe connections, I highly recommend making it permanent. In my case, the <EM>snc/only_encrypted_rfc</EM> parameter is sufficient, but you might consider setting a few others as well, such as <EM>snc/accept_insecure_cpic</EM>, <EM>snc/accept_insecure_gui</EM>, <EM>snc/accept_insecure_rfc</EM>, <EM>snc/only_encrypted_gui</EM>.<BR /> <BR /> I can set the parameter to 1, which enforces encryprion for non-ABAP RFC connections. Higher levels enforces encryption for ABAP and intenal connections.<BR /> <PRE><CODE>snc/only_encrypted_rfc = 1</CODE></PRE><BR /> Now the call should be rejected by the system.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/nwrfcsdk/bin$ ./startrfc -h sandbox -s 00 -u rfcuser -p secure123 -c 001 -t 3 -i<BR /> Error: Unencrypted communication is rejected by this system</CODE></PRE><BR /> It is no longer possible to establish an unencrypted connection.<BR /> <H1 id="toc-hId--360495794">SAP Cryptographic Library installation</H1><BR /> To enable RFC connection encryption, it is necessary to install a cryptographic library. On SAP systems it is included along with the kernel, while here it must be installed separately. I go to the SAP Marketplace to see what the latest version is and download it. In addition, I need to get the <EM>SAPCAR</EM> program to decompress the archive. So in the end I choose 2 files and save them in a new <EM>cryptolib</EM> folder.<BR /> <PRE><CODE>SAPCRYPTOLIBP_8553-20011697.SAR<BR /> SAPCAR_1200-70007716.EXE</CODE></PRE><BR /> It's time to unpack the library:<BR /> <PRE><CODE>rfcuser@sandboxn100:~/cryptolib$ <STRONG>./SAPCAR_1200-70007716.EXE -xf SAPCRYPTOLIBP_8553-20011697.SAR</STRONG><BR /> SAPCAR: processing archive SAPCRYPTOLIBP_8553-20011697.SAR (version 2.01)<BR /> SAPCAR: 6 file(s) extracted</CODE></PRE><BR /> SAPCAR and the archive can be removed after extraction. Let's also start <EM>sapgenpse</EM> component to check if everything is fine.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/cryptolib$ ./sapgenpse | tail -10<BR /> Versions: SAPGENPSE 8.5.53 (Sep 22 2023)<BR /> CommonCryptoLib 8.5.53 (Sep 22 2023) [AES-NI,CLMUL,SSE3,SSSE3]<BR /> Build change list: 248172<BR /> <BR /> USER="rfcuser"<BR /> <BR /> Environment variable $SECUDIR is not defined!<BR /> Fallback selection of SECUDIR through HOME:<BR /> "/home/rfcuser/sec"</CODE></PRE><BR /> It would be good to set <EM>SECUDIR</EM> variable explicitly and add cryptolib folder to <EM>LD_LIBRARY_PATH </EM>variable. Let's edit .<EM>profile</EM> of the user.<BR /> <PRE><CODE>rfcuser@sandboxn100:~$ cat .profile<BR /> export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/nwrfcsdk/lib:~/secudir<BR /> export SECUDIR=/home/rfcuser/sec</CODE></PRE><BR /> <H1 id="toc-hId--557009299">Client PSE preparation</H1><BR /> In the previous sections, I generated an SSL certificate for the <EM>RFCUSER</EM>. It was saved in the file <EM>rfcuser.p12</EM>. Even if you don't generate the certificates yourself, you will probably get a ready one from the certification authority in this format. In the SAP world we rather operate on PSE repositories, so with the help of <EM>sapgenpse</EM> I will convert PKCS#12 to PSE. I will perform all operations in the rfcuser user <EM>sec</EM> folder.<BR /> <BR /> I prepared files, including certification authorities' certificates:<BR /> <PRE><CODE>rfcuser@sandboxn100:~/sec$ <STRONG>ls -l</STRONG><BR /> total 24<BR /> -rw-r--r-- 1 rfcuser rfcuser 2033 Nov 30 18:28 anotherca.cert.pem<BR /> -rw-r--r-- 1 rfcuser rfcuser 1911 Nov 30 18:29 interApps.cert.pem<BR /> -rw------- 1 rfcuser rfcuser 5875 Nov 30 18:28 rfcuser.p12</CODE></PRE><BR /> Let's import the p12 file into new repository and protect it with <EM>MyVerySecretPIN_1</EM> secret PIN.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/sec$ <STRONG>../cryptolib/sapgenpse import_p12 -x MyVerySecretPIN_1 -p SAPSNCS.pse -r anotherca.cert.pem -r interApps.cert.pem rfcuser.p12</STRONG><BR /> Please enter PKCS#12 encryption password: *****************<BR /> Found key 'INDEX=0,SIG=YES,ENC=YES,MD5-FINGERPRINT=60A1 B7F2 4F30 C198 9457 D2C3 5FA4 7F8E,KEYID=57F11B35BBC963B83B3B65F2666726003D11A46F'<BR /> PSE "/home/rfcuser/sec/SAPSNCS.pse" was written</CODE></PRE><BR /> The PIN we can encrypt in <EM>cred_v2</EM> file, which is kind of passwords repository. Later this can be used by tools to access the PSE file. I also update file permissions to more strict.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/sec$ <STRONG>../cryptolib/sapgenpse seclogin -x MyVerySecretPIN_1 -p SAPSNCS.pse</STRONG><BR /> running seclogin with USER="rfcuser"<BR /> Added SSO-credentials for PSE "/home/rfcuser/sec/SAPSNCS.pse"<BR /> rfcuser@sandboxn100:~/sec$ <STRONG>chmod go-rwx cred_v2</STRONG></CODE></PRE><BR /> Finally I have below files with PSE and cred_v2.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/sec$ ls -l<BR /> total 28<BR /> -rw-r--r-- 1 rfcuser rfcuser 2033 Nov 30 18:28 anotherca.cert.pem<BR /> -rw------- 1 rfcuser rfcuser 114 Nov 30 18:37 cred_v2<BR /> -rw-r--r-- 1 rfcuser rfcuser 1911 Nov 30 18:29 interApps.cert.pem<BR /> -rw------- 1 rfcuser rfcuser 5875 Nov 30 18:28 rfcuser.p12<BR /> -rw------- 1 rfcuser rfcuser 5111 Nov 30 18:36 SAPSNCS.pse</CODE></PRE><BR /> Let's check what was saved in the PSE. I can see main certificate, signing CA and validity dates.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/sec$ <STRONG>../cryptolib/sapgenpse get_my_name -p SAPSNCS.pse</STRONG><BR /> SSO for USER "rfcuser"<BR /> with PSE file "/home/rfcuser/sec/SAPSNCS.pse"<BR /> <BR /> Subject : CN=RFCUSER, O=AnotherCompany, SP=kuj-pom, C=PL<BR /> Issuer : CN=Intermediate Apps CA, OU=Apps, O=AnotherCompany, SP=kuj-pom, C=PL<BR /> Serialno : 72:7B:01:77:64:B6:60:0B:31:D7:6C:60:66:0A:B2:7E:AB:FD:77:B1<BR /> KeyInfo : RSA, 4096-bit<BR /> Validity - NotBefore: Thu Nov 30 17:54:25 2023 (231130165425Z)<BR /> NotAfter : Fri Nov 29 17:54:25 2024 (241129165425Z)<BR /> KeyUsage : none<BR /> ExtKeyUsage : ClientAuthentication<BR /> SubjectAltName : none</CODE></PRE><BR /> I can also confirm, that the trust list of the PSE is empty.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/sec$ <STRONG>../cryptolib/sapgenpse maintain_pk -p SAPSNCS.pse -l</STRONG><BR /> maintain_pk for PSE "/home/rfcuser/sec/SAPSNCS.pse"<BR /> PKList is empty.<BR /> <BR /> Empty trusted list.</CODE></PRE><BR /> <H1 id="toc-hId--753522804">SAP user update</H1><BR /> The next step is to prepare the <EM>RFCUSER</EM> user for SSO authentication. To do this, I update the <EM>SNC name</EM> field in the <EM>SNC</EM> tab in the <EM>SU01</EM> transaction. At the same time, I can disable the option of logging in with a password.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/rfc-user-snc-sso.png" /></P><BR /> <BR /> <H1 id="toc-hId--950036309">sapnwrfc.ini</H1><BR /> The <EM>sapnwrfc.ini</EM> file allows to configure connection parameters for RFC calls made with the SDK library. You can define parameters there, such as the details of the system you are connecting to, the method of authentication, or encryption. Of course, you can specify a username and password there, but I will be configuring a certificate-based SSO. So I create the <EM>sapnwrfc.ini</EM> file in the same directory as the <EM>startrfc</EM> program:<BR /> <PRE><CODE>rfcuser@sandboxn100:~/nwrfcsdk/bin$ <STRONG>cat sapnwrfc.ini</STRONG><BR /> DEST=a4htest<BR /> SNC_LIB=/home/rfcuser/cryptolib/libsapcrypto.so<BR /> SNC_MYNAME=p:CN=RFCUSER, O=AnotherCompany, SP=kuj-pom, C=PL<BR /> SNC_PARTNERNAME=p:CN=sandbox.mydomain.internal, OU=IT, O=MyCompany, C=PL<BR /> SNC_QOP=9</CODE></PRE><BR /> For readability, the file contains a minimum set of parameters. <EM>DEST</EM> defines the name of the connection, which must be referred to by the program making the connection. <EM>SNC_LIB</EM> defines which cryptographic library to use. <EM>SNC_MYNAME</EM> specifies the SNC name of the client. <EM>SNC_PARTNERNAME</EM> gives the SNC name of the SAP server to which we are connecting. <EM>SNC_QOP</EM> defines the scope of the SNC, where <EM>9</EM> defines the maximum available security level.<BR /> <BR /> I can return to <EM>startrfc</EM> program and update required parameters. The most important one is <EM>-D</EM>, which defines connection name, consistent with <EM>sapnwrfc.ini</EM> definition.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/nwrfcsdk/bin$ ./startrfc -h sandbox -s 00 -D a4htest -i</CODE></PRE><BR /> You might notice that the parameters responsible for the username, password and client number have been removed. They are not required if the SNC string is unique, that is, only one user on one client in a given system has this specific <EM>SNC name</EM> assigned to it.<BR /> <BR /> The connection name is essential when you are securing a application that you are not the author of. The most important thing is to find in the documentation or configuration options how to determine this parameter or how to define it. Once you know this you will most likely be able to enable secure connection and encryption, even if the documentation from the vendor does not mention anything about such feature.<BR /> <H1 id="toc-hId--1146549814">Trust relationship</H1><BR /> Ok, let's start the program to see what else is missing:<BR /> <PRE><CODE>rfcuser@sandboxn100:~/nwrfcsdk/bin$ <STRONG>./startrfc -h sandbox -s 00 -D a4htest -i</STRONG><BR /> [Thr 139683030722496] Thu Nov 30 18:50:59:304 2023<BR /> [Thr 139683030722496] *** ERROR =&gt; SncPEstablishContext() failed for target='p:CN=sandbox.mydomain.internal, OU=IT, O=MyCompany, C=PL' [/bas/753_R 3638]<BR /> Error:<BR /> LOCATION CPIC (TCP/IP) with Unicode<BR /> ERROR GSS-API(maj): Miscellaneous failure<BR /> GSS-API(min): A2210223:<STRONG>Server does not trust my certificate<BR /> path</STRONG><BR /> target="p:CN=sandbox.mydomain.internal, OU=IT, O=MyCompany,<BR /> C=PL"<BR /> TIME Thu Nov 30 18:50:59 2023<BR /> RELEASE 753<BR /> COMPONENT SNC (Secure Network Communication)<BR /> VERSION 6<BR /> RC -4<BR /> MODULE /bas/753_REL/src/krn/snc/sncxxall.c<BR /> LINE 3604<BR /> DETAIL SncPEstablishContext<BR /> SYSTEM CALL gss_i</CODE></PRE><BR /> The error message is clear - SAP server does not trust my certificate chain. What does it mean?<BR /> <BR /> The situation is as follows - the client approaches the server with a certificate, which perhaps even matches the SNC name of some user in the system. But after all, such certificate can be issued by anyone and any subject can be defined. Therefore, it is very important that the certificate is known and accepted by the server. This can be a trust relationship defined directly - by adding this particular certificate to the list. However, it can also be defined at a higher level - by trusting the certification authority.<BR /> <BR /> It is the administrator's decision, or more often security policies, at which level we establish the trust relationship. It is very convenient to add a specific CA to the trusted list and this is often the right way to go. However, be aware that this also has consequences. The organisation that issues the certificates receives the authority to authenticate users on our system.<BR /> <BR /> When we are unable to trust the certificate authority, we are required to add the leaf certificate to the list. This usually brings with it quite an inconvenience - the need to renew each certificate as it approaches its expiration date. This requires coordination with the client and, with a larger number of certificates, can be very inconvenient, especially as end certificates usually have an expiry date of one year.<BR /> <BR /> As I have full control over my certificate authorities, so I add Another Root CA to my trusted list in transaction <EM>STRUST</EM>.<BR /> <BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/smalltrustedliststrust.png" /><BR /> <BR /> Let's retry the connection.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/nwrfcsdk/bin$ <STRONG>./startrfc -h sandbox -s 00 -D a4htest -i</STRONG><BR /> [Thr 139834091542464] Thu Nov 30 18:58:31:277 2023<BR /> [Thr 139834091542464] *** ERROR =&gt; SncPEstablishContext() failed for target='p:CN=sandbox.mydomain.internal, OU=IT, O=MyCompany, C=PL' [/bas/753_R 3638]<BR /> Error:<BR /> LOCATION CPIC (TCP/IP) with Unicode<BR /> ERROR GSS-API(maj): Miscellaneous failure<BR /> GSS-API(min): A2200223:<STRONG>Peer certificate path not trusted</STRONG><BR /> target="p:CN=sandbox.mydomain.internal, OU=IT, O=MyCompany,<BR /> C=PL"<BR /> TIME Thu Nov 30 18:58:31 2023<BR /> RELEASE 753<BR /> COMPONENT SNC (Secure Network Communication)<BR /> VERSION 6<BR /> RC -4<BR /> MODULE /bas/753_REL/src/krn/snc/sncxxall.c<BR /> LINE 3604<BR /> DETAIL SncPEstablishContext<BR /> SYSTEM CALL gss_init_sec_context</CODE></PRE><BR /> There is still an error, but different one. This is also related to trust, but in opposite direction. Now client doesn't trust server. I need to add SAP system certificate or better it's CA to the client's trusted list. Let's go to <EM>SECUDIR</EM> and add it to <EM>PSE</EM>.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/sec$ <STRONG>../cryptolib/sapgenpse maintain_pk -a ca.cert.pem</STRONG><BR /> Please enter PSE PIN/Passphrase: *****************<BR /> maintain_pk for PSE "/home/rfcuser/sec/SAPSNCS.pse"<BR /> ----------------------------------------------------------------------------<BR /> Subject : OU=Security, O=MyCompany, SP=kuj-pom, C=PL<BR /> <BR /> PKList updated (1 entries total, 1 newly added)<BR /> <BR /> rfcuser@sandboxn100:~/sec$ <STRONG>../cryptolib/sapgenpse maintain_pk -a interServers.cert.pem</STRONG><BR /> Please enter PSE PIN/Passphrase: *****************<BR /> maintain_pk for PSE "/home/rfcuser/sec/SAPSNCS.pse"<BR /> ----------------------------------------------------------------------------<BR /> Subject : OU=Servers, O=MyCompany, SP=kuj-pom, C=PL<BR /> <BR /> PKList updated (2 entries total, 1 newly added)</CODE></PRE><BR /> I have to know PSE password to modify it.<BR /> <BR /> You can always your trusted list with below command:<BR /> <PRE><CODE>rfcuser@sandboxn100:~/sec$ <STRONG>../cryptolib/sapgenpse maintain_pk -l</STRONG></CODE></PRE><BR /> Now I can test the connection once more.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/nwrfcsdk/bin$ <STRONG>./startrfc -h sandbox -s 00 -D a4htest -i</STRONG><BR /> SAP System ID: A4H<BR /> SAP System Number: 00<BR /> Partner Host: vhcala4hci<BR /> Own Host: sandboxn100<BR /> Partner System Release: 754<BR /> Partner Kernel Release: 777<BR /> Own Release: 753<BR /> Partner Codepage: 4103<BR /> Own Codepage: 4103<BR /> User: RFCUSER<BR /> Client: 001<BR /> Language: E</CODE></PRE><BR /> Success. Connection is possible with SSL based authentication. Encryption is obviously enabled.<BR /> <H1 id="toc-hId--1343063319">Firewall</H1><BR /> When we consider how to secure RFC connections, it is impossible to ignore the question of the firewall. It is obvious that also at the network level, we should only allow traffic from addresses that are allowed to communicate with our server. One question to ask is which ports are needed. There are two ports that are used by the Gateway, which is responsible for RFC communication - 33&lt;NN&gt;/tcp and 48&lt;NN&gt;/tcp. NN is instance number, in my case 00. 3300/tcp is used for unencrypted communication, while 4800/tcp is the secure gateway, where communication is encrypted. In my case, after configuring a secure connection, only 4800/tcp is needed.<BR /> <BR /> However, there is one more port to be considered. It is opened by the message server, which is part of the ASCS instance, that in my case is number 01. So I would also consider opening port 3601/tcp on the firewall to allow load balancing using login groups.<BR /> <H1 id="toc-hId--1539576824">UCON</H1><BR /> The final option I wanted to recommend to make RFC connections more secure is Unified Connectivity (UCON). This is a mechanism that provides the ability to define a list of allowed remote function modules. This is related to the idea of reducing the attack surface. It is clear that systems only use a very small proportion of functional modules. As the software may contain security vulnerabilities and somewhere in the system someone may have set too broad permissions, it is worth implementing protection at a higher level. UCON introduces an extra layer of protection - even before the user's permissions are checked, it is verified whether the call is on the allowed list. However, UCON is a rather broad topic for a separate article.<BR /> <H1 id="toc-hId--1736090329">Conclusion</H1><BR /> RFC connections from external non-ABAP programmes can be secured on very many levels. Security should be a priority these days and unencrypted connections forbidden by any security policy. Although we often have less control over external programs, as you can see, quite a lot can be done in this area too.<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp; 2023-12-07T09:18:50+01:00 https://community.sap.com/t5/technology-blogs-by-members/handling-rfc-in-sap-build-process-automation/ba-p/13580244 Handling RFC in SAP Build - Process Automation 2023-12-28T12:34:38+01:00 Metehan https://community.sap.com/t5/user/viewprofilepage/user-id/172809 <H2 id="toc-hId-964758439"><STRONG>Introduction</STRONG></H2><BR /> Hello,<BR /> <BR /> I will be showing you How to handle RFC in SAP Build - Process Automation .<BR /> <H2 id="toc-hId-768244934"><STRONG>Scenario</STRONG></H2><BR /> We will be using a RFC to get data that we need in our automation.<BR /> <H3 id="toc-hId-700814148"><STRONG>Prerequisites:</STRONG></H3><BR /> <OL><BR /> <LI>Basic Knowledge about RFC</LI><BR /> <LI>Basic knowledge about SAP Build</LI><BR /> <LI>Basic knowledge about SAP Process Automation.</LI><BR /> </OL><BR /> <H3 id="toc-hId-504300643"><STRONG>Step-by-Step Procedure:</STRONG></H3><BR /> <OL><BR /> <LI>Creating the RFC .</LI><BR /> <LI>Creating the Process Automation project.</LI><BR /> <LI>Consuming RFC in our project</LI><BR /> </OL><BR /> <H3 id="toc-hId-307787138"><STRONG>STEP 1 : Creating RFC</STRONG></H3><BR /> Firstly we need to create our RFC according to our needs. Go to <EM><STRONG>' SE37 '&nbsp;</STRONG></EM> transaction and create your RFC. Do not forget to select Remote-Enabled Module processing type.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/1-67.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 1 - RFC Attributes</P><BR /> In my case, what I needed was the mail addresses of customer numbers I already had. So created my RFC to get mail addresses using company codes and customer numbers. You should set your parameters according to your needs.<BR /> You can see my parameters below.<BR /> <P style="text-align: center;overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/2-37.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 2 - Import Parameters</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/3-27.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 3 - Tables Parameters</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/4-27.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 4 - T_CUSTOMER Components</P><BR /> In my coding part I am finding mail addresses using the customer numbers and company code provided in <EM><STRONG>T_CUSTOMER</STRONG></EM> and filling <STRONG><EM>' MAIL '&nbsp;</EM></STRONG> component according to <STRONG><EM>' IV_ CHECK '</EM></STRONG> import parameter.<BR /> <H3 id="toc-hId-111273633"><STRONG>STEP 2 : Creating Process Automation Project</STRONG></H3><BR /> Now we are going to create our project.<BR /> <BR /> Go to SAP Build cockpit and click create.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/5-17.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 5 - SAP Build Create Project</P><BR /> After that click ' Build an Automated Process ' and ' Task Automation ' . Give your project a name and configure your agent and we are all set.<BR /> <H3 id="toc-hId--85239872"><STRONG>STEP 3 : Consuming RFC in Project</STRONG></H3><BR /> Firstly we need to add <EM><STRONG>BAPI SDK</STRONG></EM> to our project. To do that go to settings and then <EM><STRONG>Dependencies</STRONG></EM> section. After that click <STRONG><EM>Add Dependency</EM></STRONG> and search for <EM><STRONG>BAPI SDK</STRONG></EM>.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/6-13.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 6 - Add Dependency</P><BR /> Now we need to create our <STRONG><EM>Data Types</EM></STRONG> based on our RFC parameters. The important part here is that Data Types must be created as structures, for my case I will be creating two Data Types , one for Import Parameters of my RFC and one for Tables Parameters.<BR /> <BR /> Go to your <STRONG><EM>Project Content</EM></STRONG> and click <EM><STRONG>Create</STRONG></EM> then click <EM><STRONG>Data Type</STRONG></EM>. After that give it a proper name and lets set the Data Type.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/7-15.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 7 - Creating Data Types</P><BR /> Create your Data Types based on your RFC parameters. Here are my Data Types<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/8-14.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 8 - Data Types</P><BR /> <P style="overflow: hidden;margin-bottom: 0px">Now we can call our RFC from our project. Lets start building our project. You can see the general overview of project, I will be explaining each step.</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/9-7.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 9 - Overview of Project</P><BR /> Firstly we need to establish our connection to SAP server where RFC exist. For that we are using <EM><STRONG>Set SAP Connection (Basic)</STRONG></EM> activity and filling it as needed.<BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: SAPRegular, 'Helvetica Neue', Arial, sans-serif;overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/10-10.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 10 - Set SAP Connection (Basic)</P><BR /> To be sure whether we were able to connect to SAP system or not we are using <EM><STRONG>Is SAP Connection Alive</STRONG></EM> activity.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/11-10.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 11 - Is SAP Connection Alive</P><BR /> <P style="overflow: hidden;margin-bottom: 0px">For next step we are creating our variable using the Data Types that we created.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/12-9.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 12 - Creating the RFC Import Variable</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/13-8.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 13 - Creating the RFC Tables Variable</P><BR /> Now that we created our variables , we are going to fill these variables. Firstly we are checking if the SAP Connection is alive or not after that we are filling our variables as we need.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/14-6.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 14 - Filling Variables</P><BR /> Now we can execute our RFC and get the desired data. To call our RFC we are using <EM><STRONG>Execute BAPI</STRONG></EM> activity. And to reach our desired data we are using <EM><STRONG>output parameter of Execute BAPI</STRONG></EM> in a <EM><STRONG>Custom Script</STRONG></EM> activity as you can see below.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/15-6.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 15 - Execute RFC</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/16-5.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 16 - Desired Data From RFC</P><BR /> Here is our mail addresses corresponding to customer numbers and company codes.<BR /> <H2 id="toc-hId--410836096"><STRONG>Conclusion</STRONG></H2><BR /> If you read the blog well congratulations ! You learned How to create a new project in SAP Build, How to create custom Data Types in a SAP Process Automation, How to consume a RFC in SAP Process Automation and much more.<BR /> <BR /> <EM>If this blog is a help to you please like and share <span class="lia-unicode-emoji" title=":slightly_smiling_face:">🙂</span>&nbsp;</EM><BR /> <DIV><BR /> <DIV><BR /> <BR /> <EM>Also Please do not hesitate to ask any further questions and feel free to share your feedback on the content.</EM><BR /> <BR /> <EM><STRONG>Thank you!</STRONG></EM><BR /> <PRE><CODE><STRONG>- Metehan Dülger </STRONG></CODE></PRE><BR /> </DIV><BR /> <DIV></DIV><BR /> </DIV> 2023-12-28T12:34:38+01:00 https://community.sap.com/t5/application-development-blog-posts/created-a-program-to-fetch-customer-details-from-as400-system-to-sap-s4hana/ba-p/13619246 Created a program to fetch customer details from AS400 system to SAP S4HANA via RFC FM 2024-02-28T13:31:37.538000+01:00 harsh_raj1 https://community.sap.com/t5/user/viewprofilepage/user-id/152044 <P>Creating a program to fetch customer details from an AS400 system to SAP S/4HANA via RFC (Remote Function Call) involves several steps. Below is a simplified example to illustrate the process. Note that you need the appropriate authorization and system connectivity settings for RFC communication.</P><H3 id="toc-hId-1116273783">Using Transaction SM59:</H3><OL><LI><P><STRONG>Log in to SAP GUI:</STRONG></P><UL><LI>Log in to the SAP GUI using the appropriate credentials.</LI></UL></LI><LI><P><STRONG>Open Transaction SM59:</STRONG></P><UL><LI>Enter transaction code SM59 in the command field and press Enter.</LI></UL></LI><LI><P><STRONG>Choose RFC Connection:</STRONG></P><UL><LI>In the SM59 screen, navigate to the "RFC Connections" folder in the left-hand tree structure.</LI></UL></LI><LI><P><STRONG>Create RFC Destination:</STRONG></P><UL><LI>Right-click on the "RFC Connections" folder, choose "Create," and select the appropriate connection type (for example, "TCP/IP Connections" for remote systems).</LI></UL></LI><LI><P><STRONG>Enter Connection Details:</STRONG></P><UL><LI>Fill in the required details for the RFC destination, including the connection type, the target system's IP address or hostname, and the system number.</LI></UL></LI><LI><P><STRONG>Configure Logon &amp; Security:</STRONG></P><UL><LI>Configure the logon and security settings. This might include specifying the user credentials that will be used for communication.</LI></UL></LI><LI><P><STRONG>Additional Parameters:</STRONG></P><UL><LI>Depending on your scenario, you may need to configure additional parameters, such as language, code page, or other connection-specific settings.</LI></UL></LI><LI><P><STRONG>Test Connection:</STRONG></P><UL><LI>Before saving the RFC destination, you can use the "Connection Test" button to check if the connection to the target system is successful.</LI></UL></LI><LI><P><STRONG>Save the RFC Destination:</STRONG></P><UL><LI>Once the connection test is successful, save the RFC destination.</LI></UL></LI><LI><P><STRONG>Activate and register&nbsp;the RFC Destination:</STRONG></P><UL><LI>After saving the destination, you may need to activate and register it. The activation ensures that the settings take effect.</LI></UL></LI><LI><P><STRONG>Use the RFC Destination in ABAP Programs:</STRONG></P><UL><LI>You can use the created RFC destination in ABAP programs by calling the remote function modules defined in the target system.<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_0-1708951919820.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71246i814B426F5B50173C/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_0-1708951919820.png" alt="harsh_raj1_0-1708951919820.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_1-1708952589257.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71264i55F1949E37D8B5EF/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_1-1708952589257.png" alt="harsh_raj1_1-1708952589257.png" /></span><P><STRONG>Create RFC-Enabled Function Module in SAP S/4HANA:</STRONG></P><UL><LI>Create an RFC-enabled function module in SAP S/4HANA that will call the RFC function module in the AS400 system. This function module should take any necessary parameters, call the RFC function module in the AS400 system, and return the customer details. <span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_4-1708949394238.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71182i6D2B21728C58811B/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_4-1708949394238.png" alt="harsh_raj1_4-1708949394238.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_5-1708949436424.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71183i4D1D8A442E2B49C7/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_5-1708949436424.png" alt="harsh_raj1_5-1708949436424.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_6-1708949471493.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71184i6DE369551A825D78/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_6-1708949471493.png" alt="harsh_raj1_6-1708949471493.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_7-1708949530552.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71186iD7FE2FCC6E8AF505/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_7-1708949530552.png" alt="harsh_raj1_7-1708949530552.png" /></span></LI></UL></LI></UL></LI></OL><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code>FUNCTION zhr_fm_knb1_fico. *"---------------------------------------------------------------------- *"*"Local Interface: *" IMPORTING *" VALUE(IM_KUNNR) TYPE ZHR_TTY_KNB1 OPTIONAL *" EXPORTING *" VALUE(GT_KNB2) TYPE ZHR_TT_KNB1 *" VALUE(EP_MSG) TYPE STRING *" TABLES *" GT_KNB1 STRUCTURE KNB1 *"---------------------------------------------------------------------- IF im_kunnr IS NOT INITIAL. SELECT FROM knb1 FIELDS kunnr, bukrs, erdat, ernam WHERE kunnr in _KUNNR INTO CORRESPONDING FIELDS OF TABLE _knb2 . IF gt_knb1 IS INITIAL. ep_msg = 'No record found'. ENDIF. ENDIF. ENDFUNCTION.</code></pre><P>&nbsp;</P><P>&nbsp;<SPAN>Creating a report program in SAP S/4HANA using the ABAP Editor (SE38) involves defining a report using the Report&nbsp;</SPAN><SPAN>statement, fetching data from the database, and displaying the results. Below is a simple example of a report program that retrieves and displays data from knb1 table.</SPAN></P><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code>*&amp;---------------------------------------------------------------------* *&amp; Report ZHR_RP_FM *&amp;---------------------------------------------------------------------* *&amp; *&amp;---------------------------------------------------------------------* REPORT ZHR_RP_FM. DATA: lv_kunnr TYPE kunnr. * SELECT-OPTIONS: s_kunnr FOR lv_kunnr. DATA: lt_range type RANGE OF kunnr. lt_range = VALUE #( sign = 'I' option = 'BT' ( low = s_kunnr-low ) ( high = s_kunnr-high ) ). DATA: lt_knb1 TYPE TABLE OF knb1, gt_knb1 TYPE TABLE of knb1, * gs_knb1 TYPE knb1, lv_msg TYPE string. START-OF-SELECTION. * CALL FUNCTION 'ZHR_FM_KNB1_FICO' DESTINATION 'zhr_a4hana_to_s4hana' EXPORTING im_kunnr = lt_range IMPORTING GT_KNB2 = gt_knb1 "gs_knb1 EP_MSG = lv_msg tables gt_knb1 = lt_knb1 . IF sy-subrc &lt;&gt; 0. * Implement suitable error handling here ENDIF. IF gt_knb1[] is NOT INITIAL. cl_demo_output=&gt;display( gt_knb1 ). ENDIF.</code></pre><P>&nbsp;</P><P>output:</P><P>give the input and click on execute button.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_0-1708950301655.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71237i5C48F50B46E7A013/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_0-1708950301655.png" alt="harsh_raj1_0-1708950301655.png" /></span></P><P>provide your user-id for s4hana along with password and click on enter.</P><P>it will display the desired output.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_2-1708952759789.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71268i24414975FFD71A86/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_2-1708952759789.png" alt="harsh_raj1_2-1708952759789.png" /></span></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_2-1708950014638.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71236iB4474CFD26FF86B1/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_2-1708950014638.png" alt="harsh_raj1_2-1708950014638.png" /></span></P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P> 2024-02-28T13:31:37.538000+01:00 https://community.sap.com/t5/technology-blogs-by-members/create-trusted-rfc-with-specific-technical-user/ba-p/13694181 Create trusted RFC with specific technical user 2024-05-08T17:46:41.940000+02:00 Austin_Nguyen https://community.sap.com/t5/user/viewprofilepage/user-id/42832 <P><SPAN>As the SAP Basis administrator, we know that we can establish the trusted RFC between ABAP systems in which we can connect to the target system with our current user without providing the credentials like in screenshot below.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_0-1715101552453.png" style="width: 514px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106978i86E93B9327375E79/image-dimensions/514x135?v=v2" width="514" height="135" role="button" title="austinnguyen_0-1715101552453.png" alt="austinnguyen_0-1715101552453.png" /></span></P><P><SPAN>But what if we want to use a specific technical user and still want to benefit from trusted RFC? Actually, we can do it with the same method and I will show you how in this blog post.</SPAN></P><P><SPAN>First of all, since we need to create the trusted RFC, we need to establish the trusted relationship between systems through transaction code SMT1. In the scope of this blog, I’ll assume that we need to define the trust between system AA and BB.</SPAN></P><P>1.&nbsp;<SPAN>Go to SMT1 Tcode on AA, and click the “Create” button to start the process.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_1-1715101603516.png" style="width: 605px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106979i9C45744ADD2F458A/image-dimensions/605x223?v=v2" width="605" height="223" role="button" title="austinnguyen_1-1715101603516.png" alt="austinnguyen_1-1715101603516.png" /></span></P><P>2.&nbsp;<SPAN>Click “Continue”.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_2-1715101638658.png" style="width: 607px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106980i307F7AC367BA5FAB/image-dimensions/607x492?v=v2" width="607" height="492" role="button" title="austinnguyen_2-1715101638658.png" alt="austinnguyen_2-1715101638658.png" /></span></P><P>3.&nbsp;<SPAN>On the next screen, we need to provide the information about the target server and login information. It'll create a new RFC on the target server called "TRUSTING@&lt;SID&gt;xxxxxxxx".</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_3-1715101658069.png" style="width: 612px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106981i0BD4AF7A26B6AF6E/image-dimensions/612x491?v=v2" width="612" height="491" role="button" title="austinnguyen_3-1715101658069.png" alt="austinnguyen_3-1715101658069.png" /></span></P><P>4.&nbsp;<SPAN>On the following screens, just click on “Continue” and “Finish” on the final screen.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_4-1715101674781.png" style="width: 611px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106982i1538606103989217/image-dimensions/611x489?v=v2" width="611" height="489" role="button" title="austinnguyen_4-1715101674781.png" alt="austinnguyen_4-1715101674781.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_5-1715101685108.png" style="width: 614px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106983iC1E281E0154BCD03/image-dimensions/614x494?v=v2" width="614" height="494" role="button" title="austinnguyen_5-1715101685108.png" alt="austinnguyen_5-1715101685108.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_6-1715101700657.png" style="width: 615px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106984i5F579CE9E71E7F78/image-dimensions/615x492?v=v2" width="615" height="492" role="button" title="austinnguyen_6-1715101700657.png" alt="austinnguyen_6-1715101700657.png" /></span></P><P>5.&nbsp;<SPAN>Now, it’s finished on the first system AA and you need to do the same steps on the second system BB.</SPAN></P><P><SPAN>Next, we need to make sure that the technical user on the source system has enough authorizations to allow the trusted call from the source system.</SPAN></P><P><SPAN>For that purpose, the user role needs to have the authorization object S_RFCACL. Below is the description of its field.</SPAN></P><UL><LI><SPAN>ACTVT: always 16. It’s the only value we can specify.</SPAN></LI><LI><SPAN>RFC_CLIENT: In this field, we can specify which client we allow to make the trusted connection. For example: the AA system has 3 clients 001, 002, and 003, but if we want to grant the trusted connection from client 002 only, then we need to specify here the value 002. The connection from clients 001 and 003 will be rejected.</SPAN></LI><LI><SPAN>RFC_EQUSER: This is the important field for making trusted RFCs with another user. In this case, we want to connect with a specific technical user, therefore we set it to value “</SPAN><STRONG>N</STRONG><SPAN>”.</SPAN></LI><LI><SPAN>RFC_INFO: the installation number of the calling system. We can set it to ‘*’, then the role can be used by multiple source systems, or you can specify here the list of installation numbers that allow you to create a trusted connection.</SPAN></LI><LI><SPAN>RFC_SYSID: SID of the calling system.</SPAN></LI><LI><SPAN>RFC_TCODE: Calling transaction code.</SPAN></LI><LI><SPAN>RFC_USER: ID of the calling user.</SPAN><P><SPAN>After finishing the role creation, please make sure that the role will be assigned to the technical user on the called system.</SPAN></P><P><SPAN>We have come to the final step. For details on creating the RFC in SM59, please refer to the SAP help documentation. In this blog, I’ll focus only on trusted RFC settings.</SPAN></P><P><SPAN>After specifying the target hostname and SID, go to the Logon &amp; Security tab and set the Trust Relationship to “Yes”.</SPAN></P><P><SPAN>Now, instead of setting the checkbox at “Current User”, we will leave it blank and give the information about the technical user from the called system. Of course, the password is no longer necessary because we’re creating a trusted connection.</SPAN></P></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_7-1715101766516.png" style="width: 624px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106985iE4C7DD2969ED5D7A/image-dimensions/624x496?v=v2" width="624" height="496" role="button" title="austinnguyen_7-1715101766516.png" alt="austinnguyen_7-1715101766516.png" /></span></P><P><SPAN>Save the connection and execute “Authorization Check”.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_8-1715101778797.png" style="width: 628px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106986i70A61F858AB0F4C4/image-dimensions/628x295?v=v2" width="628" height="295" role="button" title="austinnguyen_8-1715101778797.png" alt="austinnguyen_8-1715101778797.png" /></span></P><P><SPAN>At this point, if you log in to the called system and go to TCode SM59. Then you will see the connection from the calling system but from that technical user, not ours.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_9-1715101791303.png" style="width: 633px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106987i77B6B1D9077CE4C3/image-dimensions/633x45?v=v2" width="633" height="45" role="button" title="austinnguyen_9-1715101791303.png" alt="austinnguyen_9-1715101791303.png" /></span></P><P><SPAN>I hope that blog will find you well. If you have any questions or concerns so far, feel free to contact me.</SPAN></P> 2024-05-08T17:46:41.940000+02:00