Custom Single Sign-on for SAP Mobile Applications
Mobile devices bring specific challenges to a Single Sign-On (SSO) implementation if you are outside of the corporate network, along with UI problems on small devices that make password entry difficult.
This blog is the story of a project to implement single sign-on with Neptune mobile applications for a pharmaceutical organisation, but the principles transfer to any SAPUI5 mobile application including Fiori.
Effective Single Sign-On must be secure and convenient. Our customer wanted their application to:
- be secure against device loss with encryption and frequent authentication
- not require typing of passwords on the small mobile device, preferring PIN
- use only one-off Windows passwords from Active Directory
Neptune Software allows a developer to create SAPUI5 applications in the Neptune Application Designer (NAD) that can be used with a web browser on any device.
Neptune allows you to bundle the web application using Adobe PhoneGap with Apache Cordova to create a native application for iPhone (iOS), Android and Windows Mobile. The bundled application stores the SAPUI5 application on the device, and accesses data through JSON web services. The main benefits of creating a PhoneGap app are a superior mobile experience, and the ability to use the application with cached data when offline.
My colleague Björn has recently published a great four-part blog series on creating offline applications with Neptune. Part three covers further information on the architecture.
Standard Solutions for Mobile
When concerns were raised that logging on to our custom app was ruining the user experience, I travelled to the customer’s office to work with their SAP basis administrator to come up with a solution.
He had a room booked for the duration and we set up our laptops to start trying proof of concept solutions. We began by picking through the five standard authentication methods that Neptune offers.
The PIN Code optionallows the user to log on with SAP username and password once, choose a PIN, then the PIN is used to encrypt the device data. Opening the app again requires only the PIN to unlock it. We used this option to demonstrate Neptune to our customer, but during the project it became clear that they don’t use SAP passwords so it was ruled out.
SAP Enterprise Portal and ADFS were ruled out as they required password entry each time. SMP/HCPms and SAP Mobile Secure were discounted as our customer did not have the relevant infrastructure or cloud subscriptions in place.
Our customer has CyberSafe TrustBroker for SSO to SAP on the desktop. They had it configured for our applications already, but as the iPhones are not members of the Windows domain, TrustBroker had no way to identify the user apart from asking for a username and password.
Creative use of Standard Solutions
Out of obvious ideas, we started looking at some more creative solutions. x509 client SSL certificates seemed like a real gift as we discovered the customer’s AirWatch Mobile Device Management (MDM) software placed an x509 certificate on each device that identified the user. x509 is fully supported by SAP ABAP stacks, and it was a breeze to configure and prove the concept in the Safari mobile browser on the iPhones.
When we tested the iPhone app, it was not passing the x509 certificates. Some understanding of how iPhone native apps are able to access the stored certificates clarified that our application would never be able to access the certificates in the Apple keychain access group, and a call to Neptune support confirmed they had faced similar issues with PhoneGap. I have an open post on Neptune’s site with some further details and discussion from others facing similar scenarios.
The set-back left a subdued atmosphere in the office, but a meeting with our customer’s security team revealed they have Okta, a SAML 2.0 identity provider. Okta was already in use for other mobile applications and provided a good mobile PIN-based user experience, and SAML 2.0 is fully supported by the SAP ABAP stack. We had a potential solution again, and I was impressed with how easy Okta was to configure compared to other SAML 2.0 identity providers.
The high point before another fall came as we saw how well Okta worked on the desktop. The problems surfaced on mobile again, as the usable mobile interface with PIN functionality only worked if you started from the Okta app. Accessing Okta on the web meant entering the username and password each time. Inside the iPhone app, our only option was to integrate the Okta web page so we were back to square one.
Enter a custom solution: TrustBroker auth.do
CyberSafe were keen to meet to talk about a custom integration between TrustBroker and our iPhone application, and we were certainly keen to meet them. In the meeting we learned TrustBroker offers a web service named auth.do that dishes out an SAP cookie from a Windows username and password, and that was something we could work with.
What does “authenticated” actually mean for web and mobile SAP applications?
Cookies are small parcels of data sent by a web server, in an HTTP header, then stored in your browser. SAP application servers send a cookie named MYSAPSSO2 after you have logged in successfully, and having a valid MYSAPSSO2 cookie means you are authenticated.
So the objective of any authentication method for an SAP web or mobile application is to obtain, store and use a MYSAPSSO2 cookie.
PhoneGap mobile apps are essentially a web browser (a UIWebView on iPhone) with the HTML content for the application stored locally. PhoneGap includes some tricks to call up data from the SAP server domain, supporting cookies and other domain-specific functionality despite actually being stored locally.
Design of the custom SSO solution
The standard PIN code functionality in Neptune works by asking the user for an SAP username and password once, then stores these (and all other offline app data) encrypted by a PIN number. When it needs to authenticate to the SAP server, it gets the PIN from the user then calls up a web service with the SAP username and password to get a cookie.
Our approach was incredibly simple when we had settled on it. We would replace the standard SAP logon service in the standard Neptune code with the TrustBroker auth.do service. The crucial difference was that auth.do took the Windows username and password instead of an SAP one.
The final hurdles
Having declared what had now become a high profile problem as “hypothetically solved” to our customer’s manager, our project manager and even our managing director, I patiently waited for my colleague to paste the TrustBroker auth.do service into the standard code and prove the concept. Nothing is ever that easy.
Neptune uses jQuery ajax calls to call web services from the SAP server. The SAP authentication service uses form data to pass the username and password, whilst auth.do used 401 Basic Authentication so we adapted the code to send an Authentication header.
My colleagues Ross and Vijay set up a MacBook for debugging the iPhone application over USB, and also set up an HTTP test app HTTPBot which can send custom HTTP requests.
They tried using GET and POST methods. GET calls to the auth.do service didn’t work in Safari but worked in Chrome. POST calls to the auth.do service worked in HTTPBot, but not when called from our app.
HTTP POST to auth.do
POST requests were reasonably easy to figure out. HTTPBot worked, our app and the browser didn’t. I configured HTTPBot to send exactly the same request headers as I could see our app sending in the debugger, even down to the User-Agent header that tells a server what the client is. As soon as I identified HTTPBot as a browser, it stopped working.
In the content of the broken responses, SAP was trying to display an HTML document saying “Your request is being processed…” which of course is not suitable for a web service that is not seen by any human. TrustBroker is implemented with a BSP controller and the same behaviour is reported online for POST calls to other BSP applications.
HTTP GET to auth.do
As POST is not really the correct method for this case anyway, and would not work, I was faced with fixing the GET calls. The Authentication header was disappearing in the request despite us programming it correctly. I eventually enabled a trace on the SAP server and watched the request and headers coming in and out – and they did not match what the debugger displayed!
We called /cstb/oc/auth.do, and the trace showed SAP was replying with a 302 Redirect to /cstb(bD1lbiZjPTAwMA==)/oc/auth.do. The ajax call in Safari was following the redirect, but did not send the Authentication header the second time. The debugger was hiding the redirect from us, showing only the second call. On the advice of CyberSafe’s support, we called /cstb(bD1lbiZjPTAwMA==)/oc/auth.do and it worked perfectly.
I don’t mind admitting I was quite excited by the small victory, mainly due to the combination of teamwork, investigation and quiet technical study that was involved to get there. Vijay quickly had the app updated and we had a fully working custom SSO solution working perfectly on mobile.
The final mystery: what is the (bD1lbiZjPTAwMA==)string that SAP was adding to the URL in the redirect? I’ve seen these bracketed strings a thousand times, but never really wondered what they are. Equals signs on the end of a string are always a clue of base64 encoding, and a quick base64 decode reveals it’s just a language and client parameter l=en&c=000.
An application that works offline was fundamental to our project, and we had niggling doubts whilst investigating all SSO solutions that they would fail when they couldn’t display their webpage or connect to their server. The beauty of our solution was that it used the functionality that already exists in Neptune, and the offline encrypted storage still worked perfectly.
If the call to auth.do fails for an authentication error, it asks the user to try again. If the call fails for a network error, we check the PIN is correct then let the user carry on offline. It’s exactly as Neptune standard and works brilliantly.
Don’t home brew authentication
When requests for us to make a custom SSO solution started to surface, I was concerned about us developing an authentication method of any kind and introducing security problems.
I was comfortable with our solution because it did not include any development of authentication, but merely integration. TrustBroker already creates a trusted MYSAPSSO2 cookie from Windows credentials, and the encrypted storage is already used in standard Neptune. We have integrated these components as we would do in any SSO project, with code rather than configuration.
I would not personally countenance any creation of encrypted credential storage code or any mechanism that authenticates a user without the team and equipment to develop and test it properly. As well as the risk, it is duplication given the myriad of options on the market. A defining feature of this project was the sheer number of fully supported options we had from different vendors.
The easy bit: on the desktop
Our apps also work on the desktop, so we couldn’t forget that part.
In a web browser for Neptune or SAP Fiori, you can use any authentication method that is supported by the SAP ABAP stack. Throughout the course of our investigations we used Okta with SAML2.0, CyberSafe TrustBroker and Client SSL Certificates and they all work as documented.
In previous projects I’ve also configured Microsoft ADFS with SAP through SAML2.0 and it works really well, although I liked the way TrustBroker handles the case of a single Windows user having multiple SAP users associated with it, and the flexible failure modes and level of authentication challenge for different functionality. Okta was also a very easy-to-use alternative SAML2.0 identity provider based in the cloud.
The technical background everyone brought to the project was absolutely vital to creating the new solution, and it was a great example of building something new on solid technical foundations. Everyone also learned a lot, and I think it’s fair to say I spent as much time on SSO for this one project as I have in my career prior.
I’d now be confident to integrate any existing SSO solutions into SAP Fiori or Neptune applications, on mobile or desktop. As long as the SSO vendor supports SAP and makes their product available to us in a suitable API it can be done.