Friday, November 16, 2018

Beware: SAP Gateway services can default not be Cross-Domain / CORS accessed

In our business context we have non-SAP web applications that invoke SAP Gateway services to retrieve business data. This week I was involved in a rewrite of such application (the need for rewrite being that another consumed data source, namely a SharePoint List, was moved to a new destination, from on-premise SharePoint 2010 to Office 365 SharePoint Online). While testing the updated application codebase, I noticed that I unexpected run into data retrieval issues with getting the SAP data; on code that I did not even touch. After some investigation, the cause appeared to be a Cross Domain issue: the consumed SAP Gateway services are deployed on another domain as the application (whether run local via Node.js, or on the target webserver). The problem was known to application owner, and pragmatic solution to use the application only from Internet Explorer (IE); as that includes an option to disable the Cross Domain check. Mind you, I initially did my testing via Chrome and Edge; both browsers do not support to skip the Cross Domain check in their default usage behavior.
Having a developer and solution-aware mindset, I then thought to fix the application itself to enable Cross Domain data access. All browser support this via CORS. Change in the JavaScript codebase should be simple, call the service requests with Cross-Domain awareness: see Using CORS. However, even with this code change the application (or rather the browser) failed to retrieve the data from the SAP Gateway services. With developers tools I inspected the network traffic, and identified the problem. The PreFlight request issued by the browser for non-simple CORS data requests, are responded by the SAP Gateway application with HTTP 401.
This is not compliant with the CORS specification: Preflight requests must not include the user credentials. See the W3C Cross-Origin Resource Sharing specification, preflight request
All modern browsers obey to the CORS specification, and do intentionally not include Authorization in the Preflight OPTIONS request. SAP NetWeaver should respond with sending the CORS response, and next the succeeding actual http request (with GET, POST, PUT, or DELETE method) will include Authorization information: this is the call that actually goes into the SAP backend to access the stored business data.
The SAP Gateway specific cause is written in post How to Enable CORS on SAP NetWeaver Platform:
...why is the Preflight Request failing? The issue lies in how a Preflight Request is constructed. According to the CORS specification, the Preflight Request must NOT carry any user credential. As most applications on NetWeaver require user authentication, the Preflight Request will get an “HTTP 401 Unauthorized” error message, thus failing the request.
The post also describes an approach to resolve it directly on SAP Netweaver level, via combination of SICF configuration and ICM rewrite rules. Another approach can be to utilize a reverse proxy in the network infrastructure, and let that handle the CORS handling in front of the SAP NetWeaver destination.

Sunday, March 26, 2017

SharePoint integration endpoints for a SAPUI5 based PeopleFinder

SAPUI5 is a suitable framework to build responsive-design UIs that renders to the available screen estate of diverse device types: smartphone, tablet, and desktop. It is therefore a fit to deliver an alternative UI to SharePoint's PeopleFinder functionality, in case the out-of-the-box SharePoint UI (that is, with potentially the rendering still made company specific via customized Search Display Templates) for whatever reason does not qualify as sufficient fit. The basic requirement of a SAPUI5 mobile application is that it can consume data and functionality via OData REST services. The SharePoint platform supports such an architecture via the standard SharePoint REST services:
The integration surface for a peoplefinder functionality comprises 3 main elements:
  1. To interactive present people suggestions to user while typing in characters of the people name ==> Get names list of matched users on search input
  2. Get detailed list of matched users on search input
  3. Get details for selected user
1. Get names list of matched users on search input

Best:
SharePoint end-point 
https://<SharePoint root-url>/_api/search/query?querytext='preferredname:Jones*'''&selectproperties='PreferredName'&sourceid='B09A7990-05EA-4AF9-81EF-EDFAB16C4E31'&rowlimit=10

Alternative is to search in User Information List:
SharePoint end-point 
https://<SharePoint root-url>/_vti_bin/listdata.svc/UserInformationList?$filter=((ContentType eq 'Person') and (substringof('Jones',LastName)))&$orderby=Name

but this has some disadvantages:
  • Incomplete qua users: user is only added to UserInformationList on first visit to SharePoint site; users not visited yet, are not included
  • Overcomplete: UserInformationList is never cleaned up, former colleagues remain in the list
  • Incomplete qua search: UserInformation does not contain a full name field
2. Get detailed list of matched users on search input

Search in full content / all crawled people data fields:
SharePoint end-point https://
<SharePoint root-url>/_api/search/query?querytext='Mobile*'&selectproperties='FirstName,LastName'&sourceid='B09A7990-05EA-4AF9-81EF-EDFAB16C4E31'&rowlimit=10

Search in identified property-field(s) only:
SharePoint end-point https://
<SharePoint root-url>/_api/search/query?querytext='department:Mobile*'&selectproperties='FirstName,LastName'&sourceid='B09A7990-05EA-4AF9-81EF-EDFAB16C4E31'&rowlimit=10
3. Get details for selected user

Get all public properties:
SharePoint end-point https://
<SharePoint root-url>/_api/SP.UserProfiles.PeopleManager/GetPropertiesFor(accountName=@v)?@v='<uname of user>'

Get one single identified user profile property only:
SharePoint end-point 
https://<SharePoint root-url>/_api/SP.UserProfiles.PeopleManager/GetUserProfilePropertyFor(accountName=@v,propertyName='AboutMe')?@v='<uname of user>'

Thursday, December 22, 2016

Reverse Proxy must not decode Fiori URLs

‘Double Encoding’ issue with Fiori Urls in case of Apache-based Reverse Proxy

The typical infra architecture of an on premisse Fiori deployment includes a reverse proxy that enables access to the Fiori Apps from the internet. A responsibility of the reverse proxy is to forward the received external uri address to the protected internal Fiori resource. The generic pattern here is that the domain part of the external url is mapped to the internal url, and the remainder of the external url is concattenated to the internal url. Some / most reverse proxy products handle encoded special characters in the remainder part, well special, by decoding them before forwarding. However, (a.o.) for Fiori URLs this behaviour is undesired. The encoded characters must be forwarded as is, so that the web dispatcher on Gateway FES can decode them and process the correct decoded uri.
Clarification of the effect due 'double encoding' of Fiori URL:
  1. Browser requests "https://<external-DNS>/sap/opu/odata/UI2/PAGE_BUILDER_PERS/PageSets('%2FUI2%2FFiori2LaunchpadHome')?$expand=Pages/PageChipInstances/Chip/ChipBags/ChipProperties,Pages/PageChipInstances/RemoteCatalog,Pages/PageChipInstances/ChipInstanceBags/ChipInstanceProperties,AssignedPages,DefaultPage&sap-cache-id=...";
  2. SAP Gateway FES returns http error 404;
  3. Error logged on the SAP NetWeaver node is that "http://<SAP web dispatcher / Gateway FES>:8000/sap/opu/odata/UI2/PAGE_BUILDER_PERS/PageSets('%252FUI2%252FFiori2LaunchpadHome')?$expand=Pages/PageChipInstances/Chip/ChipBags/ChipProperties,Pages/PageChipInstances/RemoteCatalog,Pages/PageChipInstances/ChipInstanceBags/ChipInstanceProperties,AssignedPages,DefaultPage&sap-cache-id=..." is an invalid URI

Tuesday, November 1, 2016

Qualities of SAP Fior Apps

Few months ago, SAP published document "Qualities of SAP Fiori Apps (July 2016)". This document is aimed at customers and partners and defines the qualities to be met by a SAP Fiori app. It covers design, implementation and technical criteria to be met beyond the SAP product standards. Thus a handy resource to utilize for reference and guidance. However, as result of SAP's recent changes on SCN, the link became a deadlink and can current not be successful viewed via SAP locations. As I downloaded the document before, I make it available here in awaiting for SAP to structural recover their document link on SCN and/or HANA EA Explorer.

Friday, September 30, 2016

Why is Fiori adoption lagging behind?

Yesterday I attended a meeting of the Dutch SAP User Group (VNSG) on the topic ‘Customer Fiori Experiences’. As usual, the audience was mostly consultants/developers of SAP consultancies, and only a few actual end-customer attending. After interesting sessions on the state of Fiori (a.o. on SAP Fiori Cloud Edition), the meeting ended with a roundtable to share experiences. And in particular to discuss and answer on the topic how-to increase Fiori adoption in the market. According to latest numbers, (only) 10% of SAP customers world-wide are active with Fiori, and significant subset of them merely with 1 or 2 first Fiori Apps. Note, in The Netherlands the number is higher, as we’re very technology-savvy and typically run ahead of the rest of the world on adoption of new technologies.
There was large consensus in the group that the minimal actual Fiori implementations is for a major part still due unfamiliarity. Not so much by business and end-users, but by majority of SAP developers for which the step to Fiori / UI5 is [too] big, and they prefer to just stick within their comfort zone. Although there might be truth in this, I personally think the more important causes are others.
The most important is that for SAP customers there must be a tangible business case to switch to Fiori. It is not sufficient, even irrelevant for SAP organizations to switch to new technology and products just because SAP is now delivering it (and promoting it as the next great thing). Even though standard Fiori Apps do not have a license cost (anymore), there is still investment costs involved to transition from current application formats (e.g. GUI transactions, Portal application, WebDynpro) to Fiori as new UI and interaction concept. The investment costs are within preparing the IT landscape infra (introduce NetWeaver Gateway, and Fiori Front-End Server), deploying Fiori Apps plus the required underlying Gateway OData services in the SAP landscape, align with and convince Enterprise Architecture plus (IT) security that Fiori is a future-proof and secure/safe approach, educating end-users. And typically the standard Fiori Apps are not addressing the core of the specific organization, and custom Fiori Apps + Gateway OData services must be developed. And there is again the business case: if there is an existing application that still does the job, even with outdated, stone-aged layout and user-experience, there is little business motivation to invest in improving that for the internal employees. So what is needed then? In my experience and opinion, the precondition to introduce + land Fiori usage within any organization is that there is a concrete trigger – business or IT (savings). This can be that an existing SAP application (standard or custom) no longer suffices and requires to be redesigned and rebuild – and thereby introduces the opportunity to take new UI and mobility requirements into account. Or because there is a new business demand, and again in the current days with ‘mobility-first’ this must be included from beginning of. A third trigger is Application Lifecycle Management, which forces organizations to upgrade their landscape to recent NetWeaver version. Also this can be good moment to reconsider for (some) applications to migrate them into a modern UI experience.
Note, what does not help the market growth of Fiori is the SAP image: stable and robust functional platform, that you do not have to (should even) touch much. SAP could therefore also take a rewarding approach: make it tangible benificial for SAP customers to introduce Fiori => introduce new functional capabilities only via/as Fiori. Actual SAP is following this approach, with 'Fiori-tizing' S/4 HANA.

Wednesday, September 21, 2016

Resources for considering Fiori Launchpad deployment options

With the introduction in March this year of SAP Fiori Cloud Edition, SAP now supports upto 5 different deployment options for Fiori Launchpad:
  1. ABAP Front-end Server
  2. SAP Enterprise Portal, as of NW 7.31 SP12 and NW 7.4 SP7
  3. HANA Cloud Platform (HCP)
  4. SAP Fiori Cloud Edition
  5. SAP HANA Server
Which of these options is a/the best fit for an organization is largely influenced by the situation and roadmap of that specific organization. Some useful resources to aid in this deployment decision-making:
Use them at your own convenience...

Friday, June 3, 2016

SAP Web IDE cloud connectivity issues

This blog is earlier published on SAP Community Network Blogs

SAP Web IDE cloud connectivity requires project folder direct below the root node “Workspace”

In the HANA Cloud Platform cockpit I’ve setup a connection to the demo Gateway system. Next, in SAP Web IDE I’ve created a new App folder. As I prefer a manageable overview of all Apps (to be) developed in Web IDE, I created that App Folder in a subfolder beneath the Workplace folder:
This decision however gives problems within Web IDE wrt setting up the cloud connectivity.

Issue 1: neo-app.json generation is not available

Pragmatic workaround for this was to generate it via a test-App folder directly beneath Workplace, and copy + paste that file in MyApp folder. Problem resolved.

Issue 2: The destination is runtime resolved to incorrect address

Testing the MyApp in Web IDE, data is not displayed in UI. Via F12 notify that the connection to connect to the demo system is not correct resolved, and returns a 503:
For a quick test I duplicated MyApp to be directly below Workplace folder, and without making any code or configuration change, ran it from here. And now the connection is resolved, and the App displays the data from Gateway demo system:
I compared the urls generated from Web IDE to the service destination in the 2 situation. The only difference is in the 'webidetesting' part. Apparently there is some "magic" in Web IDE that reserves a dispatching url in HCP for service destinations, and that 'magic' is dependent on the project folder located direct below 'workplace'.
I considered as workaround to modify the 2nd level project in manifest.json and have it use the absolute connecting url to service:
However, that setup runs into a cross-domain issue, and is thus neither working:
The only resolution for this is to comply to the 'implicit rule' of Web IDE, and place the project folder thus direct below root node "Workplace". With the drawback that you loose the option to structure and classify your projects / Apps folders, and all need to be administrated at the same level as sibling nodes. I would rather be able to make in Web IDE visual groups of project / Apps folders per customer and / or functionality, e.g. for HR, Finance, Marketing. Perhaps we will see this functionality in a next version of Web IDE?