How to load the Fiori Launchpad from inside a UI5 application on a different domain
Sorry for the terrible title... I couldn't find a way to make this one sound better!
The problem
I recently had a client with a technical problem which I thought was an interesting one so I thought I'd share the problem and then the steps I had to take to make this technically possible.
The requirement was to load up a SAP UI5 application that lived on a Fiori Launchpad from a different application that was live on a different domain. So that we could do some work on the SAP system as the other application lived completely outside of the SAP landscape and we didn't want to expose OData services to that application as well as have the features and benefits of using the Fiori Launchpad.
So, can we load up a Fiori Launchpad app from inside of another application that's hosted somewhere else? Sure we can, let's discuss below.
Further understanding the requirement
Okay! So I want to just make a point quite clear here from the start. I did not actually want to do this and advised against it to the client. There were various reasons why I think they shouldn't have done this but much like my websql blog just because I don't agree doesn't mean that I won't talk about it.
The reason that this is technically a slight challenge is because the client didn't want to open up a new tab or window to our SAP UI5 app that lived on the Fiori Launchpad because they didn't want their end users to inadvertently leave open multiple tabs/ windows to different users. So if you're at all familiar with calling things from different domains you know that there are various security features in place to ensure that you can't do that sort of thing. In my case I want to load an app from a different domain? Well I run into a clickjacking problem.
lets see the error
I've got an SAP UI5 Fiori Launchpad that we use for internal testing/ setup of applications and other fun stuff like that. This is one of our older test systems as an such as SAP_BASIS 750 and this blog will reflect what how to overcome clickjacking in that version but I imagine this applies to many versions.
In my UI5 application I'm going to open up an Iframe to my Fiori Launchpad login screen with the following XML:
<html:iframe src="https://yourFioriLaunchPadDomain:yourPORT/sap/bc/ui5_ui5/ui2/ushell/shells/abap/FioriLaunchpad.html" target="_top" height="100%" width="100%">
</html:iframe>
Don't forget to note that I make use of the HTML namespace
here and needs to be added accordingly at the top of your XML like the below:
xmlns:html="http://www.w3.org/1999/xhtml"
If I do this somewhere in my application (in my case my local development environment) I get the following error in console:
Uncaught ClickjackingProtectionError: Clickjacking protection prevented the Fiori Launchpad to load in a frame
What is clickjacking?
Clickjacking is the idea that you can place a page/ website/ whatever that an end user trusts into an iframe and then place invisible elements on top of that frame to get you to click other things and likely open further websites/ popups and other things that we just don't want.
To ensure that a site (or in our case Fiori Launchpad) get used in a clickjacking attach you need to deny requests from things like an iframe loading your application which the SAP Fiori Launchpad does by default to all other domains.
Activate the whitelist service
Goto the transaction SICF, check that service /sap/public/bc/uics/whitelist is activated. If not activate the service.
Whitelisting our other domain
To whitelist our domain in our version of SAP we need to maintain an entry in a table, this table is the HTTP_WHITELIST
table which you can access and create a new entry via the transaction SE16
which will present you with the following screen: (note that there is no SM30 table maintenance view for HTTP_WHITELIST)
In order we should fill out the above form, starting with the entry type which for us is entry type 30
which is specifically reserved for clickjacking.
The SortKey is unique to the entry type and mandt entry, probably shows the order in which it will run through these rules but I just entered 0
.
Our protocol because we take basic security precautions servers/ domains using SSL certificates will be HTTPS
but you can enter HTTP
. I'm actually calling from my local dev environment so I'm actually going to enter a *
but I would advice against this in production environments.
For the Host this is typically going to be our domain, I would generally say that we're fine with doing *.example.com
but you can weigh the security risks yourself. I'm again not using a domain/ host as I'm using localhost so I'm going to enter in localhost
.
Port is whatever port you're running your server/ environment on I'm using port 80
so I will enter 80
which is the default web port.
URL is the 'URL pattern to check for' which I fill out as a *
which again you will have to consider if this is a good idea in your own application but I think the most important thing to check for is the host
field.
This leaves us with the below:
If we refresh our local application we should now be greeted with.... nothing. We no longer get errors but we also don't have our screen? what gives? OR you did get your screen to load but do you want to know why it does or doesn't load? I think I might not get my screen due to my SSL certificate being self signed on this system but I know that it's related to SSO/ my session cookie.
So if we're not already logged into our FLP our iframe call is failing/ loading nothing. This is as far as I can tell because our session cookie for single sign on isn't set and the FLP will not load via an iframe without it. It might be because of my SSL? It might be an issue for others... anyone else seeing this?
There are varying factors and potential workarounds to this problem that I'm not really sure I'm qualified to suggest a course of action but SSO is often implemented a bit differently depending on your workplace and I'm sure everyone will hace unique approaches that work for them on this. Let me know (if you can) your idea/ implementation in the comments!
So after logging into the Fiori Launchpad separately and re-loading our Iframe we will now see our Fiori Launchpad load up inside of our Iframe!
Showing off my own lonely tile inside of this system which is a todo list application that I help new joiners build during a UI5 workshop that I deliver.
Conclusion
That's it! we've now successfully loaded our Fiori Launchpad from a different domain and it realistically took about 10 minutes. Was this sort of post helpful? Would you like me to look into more? Let me know in the comments.
There's no reason that you couldn't do this with AngularJS, VueJS, React etc as the originating application, but I figured this is mostly a UI5 blog and this might somehow be a requirement for someone else out there in the world.
···