1) Apps Type: Mobile Banking
2) Existing Worklight Version: 6.1 (Consumer Edition)
3) Cordova Version: 3.1.0
4) Supported Platform: Android 4.2+, iOS 7+
5) Server OS: Window Server 2008
6) Application Server: IBM WebSphere Liberty Profile
7) Database: IBM DB2
The Apps was implemented with Custom Challenge handler to authenticate the user from IBM WebSeal, the ChallengeHandler fires HTTPS requests to IBM WebSeal to perform the following:
- Get login parameters from the IBM WebSeal (E.g. type of login page, Login Form submitting URL)
- Exchange encryption keys (on top of HTTPS, the Bank requires the further encrypt the traffic using jCryption)
- Submit encrypted Username/Password
All of the above steps were implemented with jQuery’s ajax(), post() or getJson() function, it is working perfectly in above setup.
The Problems
After the upgrade of Worklight 6.1 to MobileFirst 7.1, the above authentication method no longer works in Android devices, in the other hand iOS still working as intended.
After spending days in troubleshooting the detail request and response logs, we have come into a conclusion that the Android has a different context of Cookies management between jQuery’s ajax() post() with MobileFirst HTTP Requests.
Example:
By using WLJQ.ajax(… myUrl …) generate a Set-Cookie response, the Cookie will be appended automatically to all subsequence ajax request when the request are in the matching domain.
But the Set-Cookies response header from an ajax() request does not affect the following MobileFirst HTTP request functions:
1. ChallengeHandler.submitLoginForm
2. WL.Client.invokeProcedure
3. WL.Client.login
Our ChallengeHandler authenticate the user and remember the user by using cookie value, but since the cookies will not be shared between MobileFirst and jQuery, so a call to WL.Client.InvokeProcedure will be blocked by IBM WebSeal because the request was being identified as unauthenticated user.
We also observed that the user-agent for jQuery ajax/post are very different from above MobileFirst functions:
MobileFirst User-Agent: Dalvik/2.1.0 (Linux; U; Android 6.0.1; SM-G925F Build/MMB29K)/Worklight/7.1.0.0 WLNativeAPI(zerolte; MMB29K.G925FXXU3DPCN; SM-G925F; SDK 23; Android 6.0.1)
jQuery (Running on Samsung Galaxy S6)
User-Agent: Mozilla/5.0 (Linux; Android 6.0.1; SM-G925F Build/MMB29K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/49.0.2623.105 Mobile Safari/537.36/Worklight/7.1.0.0
Troubleshoot Summary
1)Update Android’s CookieManager to accept third party cookies
CookieManager cookieManager = CookieManager.getInstance(); cookieManager.setAcceptThirdPartyCookies(webView, true);
2) Manually retrieve cookie values from jQuery post() and append to MobileFirst function using WL.Client.setCookie
But due to browser restriction we were not able to retrieve Set-Cookie headers value
3) Convert all jQuery calls to use challengeHandler.submitLoginForm, but with this approach the MobileFirst session get reset after every calls of above code so it still does not work.