I have two questions.
First question:
what is the difference between the request
D/wl.request (16655): WLRequestSender.run in WLRequestSender.java:40 :: Sending request http://mywebseal:80/worklight/authorization/v1/clients/instance
and request
D/HttpPostRequestSender (3235): WLHybridRequestSender.run in WLHybridRequestSender.java:42 :: Sending request http://mywebseal:80/worklight/apps/services/api/<appname>/Android/init
I'm implementing hybrid app that uses a login form through a reverse proxy IBM WebSEAL. I'm doing the testing on Android Lollipop devices.
During the tests the WL.Client.connect
has worked correctly only once, and has carried out the request with the class WLHybridRequestSender
.
In other attempts WL.Client.connect continues to make the request using the class WLRequestSender
and without any modification to the source code.
WLRequestSender is not able to recognize the login page that returns from the Webseal Http Response.
The app has not changed and I do not understand what happened and why.
Second question:
how the WL framework decides whether to make the request using WLHybridRequestSender or WLRequestSender?
For those wishing to deepen I'm implementing http://www-01.ibm.com/support/docview.wss?uid=swg24034222 with Mobilefirst 7.0.0.00-20150729-1801 and IBM Security Access Manager for Web 8.0.1.0.
The logcat error is the following:
D/NONE(16655): Request [/apps/services/api/ISAMforMobileFirst/android/init]
W/PluginManager(16655): THREAD WARNING: exec() call to WLAuthorizationManagerPlugin.getClientInstanceIdHeader blocked the main thread for 153ms. Plugin should use CordovaInterface.getThreadPool().
D/wl.request(16655): WLRequestSender.run in WLRequestSender.java:40 :: Sending request http://mywebseal:80/worklight/authorization/v1/clients/instance
E/wl.response(16655): WLResponse.responseTextToJSON in WLResponse.java:116 :: Response from MobileFirst Platform server failed because could not read JSON from response with text {
E/wl.response(16655): document.write(warningString);
E/wl.response(16655): }
E/wl.response(16655): else{
E/wl.response(16655): document.cookie = 'acceptsCookies=yes; expires=Fri, 13-Apr-1970 00:00:00 GMT';
E/wl.response(16655): }
E/wl.response(16655): org.json.JSONException: Expected ':' after document.write(warningString) at character 32 of {
E/wl.response(16655): document.write(warningString);
E/wl.response(16655): }
E/wl.response(16655): else{
E/wl.response(16655): document.cookie = 'acceptsCookies=yes; expires=Fri, 13-Apr-1970 00:00:00 GMT';
E/wl.response(16655): }
E/wl.response(16655): at org.json.JSONTokener.syntaxError(JSONTokener.java:450)
E/wl.response(16655): at org.json.JSONTokener.readObject(JSONTokener.java:379)
E/wl.response(16655): at org.json.JSONTokener.nextValue(JSONTokener.java:100)
E/wl.response(16655): at org.json.JSONObject.<init>(JSONObject.java:155)
E/wl.response(16655): at org.json.JSONObject.<init>(JSONObject.java:172)
E/wl.response(16655): at com.worklight.wlclient.api.WLResponse.responseTextToJSON(WLResponse.java:114)
E/wl.response(16655): at com.worklight.wlclient.api.WLResponse.getResponseJSON(WLResponse.java:269)
E/wl.response(16655): at com.worklight.wlclient.WLRequest.checkResponseForSuccesses(WLRequest.java:559)
E/wl.response(16655): at com.worklight.wlclient.WLRequest.requestFinished(WLRequest.java:280)
E/wl.response(16655): at com.worklight.wlclient.WLRequestSender.run(WLRequestSender.java:52)
E/wl.response(16655): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
E/wl.response(16655): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
E/wl.response(16655): at java.lang.Thread.run(Thread.java:841)
while the logcat in case of success is the following
D/NONE(3235): Request [/apps/services/api/ISAMforMobileFirst/android/init]
W/PluginManager(16655): THREAD WARNING: exec() call to WLAuthorizationManagerPlugin.getClientInstanceIdHeader blocked the main thread for 149ms. Plugin should use CordovaInterface.getThreadPool().
D/HttpPostRequestSender(3235): WLHybridRequestSender.run in WLHybridRequestSender.java:42 :: Sending request http://mywebseal:80/worklight/apps/services/api/ISAMforMobileFirst/android/init
I/chromium(3235): [INFO:CONSOLE(27)] "Entry: ISAMOAuthChallengeHandler.isCustomResponse()", source: file:///android_asset/www/default/js/ISAMOAuthChallengeHandler/ISAMOAuthChallengeHandler.js (27)
I/chromium(3235): [INFO:CONSOLE(30)] "{"request":{"options":{"method":"post","asynchronous":true,"contentType":"application/x-www-form-urlencoded","encoding":"UTF-8","parameters":{"isAjaxRequest":"true","x":0.858127806102857},"evalJSON":true,"evalJS":true,"timeout":45000,"onAuthentication":null,"isAuthResponse":null,"requestHeaders":{"x-wl-app-version":"3.4","x-wl-app-details":"{\"applicationDetails\":{\"platformVersion\":\"7.0.0.0\",\"nativeVersion\":\"1119668270\",\"skinName\":\"default\",\"skinChecksum\":1215343974}}","x-wl-clientlog-deviceId":"be86efe08752ad62","x-wl-clientlog-appname":"ISAMforMobileFirst","x-wl-clientlog-appversion":"3.4","x-wl-clientlog-osversion":"5.0.2","x-wl-clientlog-env":"android","x-wl-clientlog-model":"Android SDK built for x86","X-WL-ClientId":"29ea85036b812a83f9922245119483e32537ce54","X-WL-Session":"e63ad99f-2453-4bcb-8a7c-f989f8211485"},"optionalHeaders":{"x-wl-clientlog-deviceId":"be86efe08752ad62","x-wl-clientlog-appname":"ISAMforMobileFirst","x-wl-clientlog-appversion":"3.4","x-wl-clientlog-osversion":"5.0.2","x-wl-clientlog-env":"android","x-wl-clientlog-model":"Android SDK built for x86"}},"transport":{"timeout":45000,"status":200,"statusText":"OK","response":"<entire html login page webseal>"
I/chromium(3235): [INFO:CONSOLE(34)] "Exit: ISAMOAuthChallengeHandler.isCustomResponse(), Response found but not CustomResponse for ISAMOAuthChallengeHandler - returning false", source: file:///android_asset/www/default/js/ISAMOAuthChallengeHandler/ISAMOAuthChallengeHandler.js (34)
I/chromium(3235): [INFO:CONSOLE(25)] "Entry: ISAMLoginFormChallengeHandler.isCustomResponse()", source: file:///android_asset/www/default/js/ISAMLoginFormChallengeHandler/ISAMLoginFormChallengeHandler.js (25)
I/chromium(3235): [INFO:CONSOLE(29)] "{"request":{"options":{"method":"post","asynchronous":true,"contentType":"application/x-www-form-urlencoded","encoding":"UTF-8","parameters":{"isAjaxRequest":"true","x":0.858127806102857},"evalJSON":true,"evalJS":true,"timeout":45000,"onAuthentication":null,"isAuthResponse":null,"requestHeaders":{"x-wl-app-version":"3.4","x-wl-app-details":"{\"applicationDetails\":{\"platformVersion\":\"7.0.0.0\",\"nativeVersion\":\"1119668270\",\"skinName\":\"default\",\"skinChecksum\":1215343974}}","x-wl-clientlog-deviceId":"be86efe08752ad62","x-wl-clientlog-appname":"ISAMforMobileFirst","x-wl-clientlog-appversion":"3.4","x-wl-clientlog-osversion":"5.0.2","x-wl-clientlog-env":"android","x-wl-clientlog-model":"Android SDK built for x86","X-WL-ClientId":"29ea85036b812a83f9922245119483e32537ce54","X-WL-Session":"e63ad99f-2453-4bcb-8a7c-f989f8211485"},"optionalHeaders":{"x-wl-clientlog-deviceId":"be86efe08752ad62","x-wl-clientlog-appname":"ISAMforMobileFirst","x-wl-clientlog-appversion":"3.4","x-wl-clientlog-osversion":"5.0.2","x-wl-clientlog-env":"android","x-wl-clientlog-model":"Android SDK built for x86"}},"transport":{"timeout":45000,"status":200,"statusText":"OK","response":"<entire html login page webseal>"
I/chromium(3235): [INFO:CONSOLE(209)] "Entry: ISAMLoginFormChallengeHandler.isPasswordChangeResponse()", source: file:///android_asset/www/default/js/ISAMLoginFormChallengeHandler/ISAMLoginFormChallengeHandler.js (209)
I/chromium(3235): [INFO:CONSOLE(259)] "ISAMLoginFormChallengeHandler.isPasswordChangeResponse returning false - not a password change response", source: file:///android_asset/www/default/js/ISAMLoginFormChallengeHandler/ISAMLoginFormChallengeHandler.js (259)
I/chromium(3235): [INFO:CONSOLE(275)] "Entry: ISAMLoginFormChallengeHandler.isLoginFormResponse()", source: file:///android_asset/www/default/js/ISAMLoginFormChallengeHandler/ISAMLoginFormChallengeHandler.js (275)
I/chromium(3235): [INFO:CONSOLE(280)] "ISAMLoginFormChallengeHandler.isLoginFormResponse - pkmslogin.form found in response.", source: file:///android_asset/www/default/js/ISAMLoginFormChallengeHandler/ISAMLoginFormChallengeHandler.js (280)
I/chromium(3235): [INFO:CONSOLE(312)] "ISAMLoginFormChallengeHandler.isLoginFormResponse - Returning true.", source: file:///android_asset/www/default/js/ISAMLoginFormChallengeHandler/ISAMLoginFormChallengeHandler.js (312)
Thanks
After the explanation of Idan if I build the app by pointing directly at MFS, the app acquires the token. Then I building again by pointing at the WebSEAL and works without problem, just because it has previously conducted the self registration. If I delete the data of the app on the Android device the issue comes up again, because the token is deleted.
So we can sum the problem by saying that the WebSEAL junction being protected, it requires properly form authentication.
But inside this junction there are both endpoints, both registration that connection.
Perhaps it should be made a specific configuration of ISAM for the initial flow of authorization?
I referred to the WebSEAL but actually the reverse proxy is made by IBM Security Access Manager for Web (ISAM), which also owns the capabilities of the WebSEAL.
In request.log on error appears this
unauthenticated 07 / Sep / 2015: 17: 25: 01 +0200 "POST / worklight / authorization / v1 / clients / instance HTTP / 1.1" 200 3552
Is useful log WireShark? Maybe not. If you want to send it anyway, now I've got to produce it.
Starting IBM MobileFirst Platform 7.0, applications are required to perform client instance registration before they are able to send additional requests to the MobileFirst Server.
Registration
andconnect
, mentioned in the question, are part of those.WLHybridRequestSender
andWLRequestSender
are classes used to accomplish this. Hybrid apps send their requests usingWLHybridRequestSender
, andWLRequestSender
is the class responsible for sending the registration request. The rest of their function is internal to the framework.According to the provided stack trace of the failing flow, what is happening is that
WLRequestSender
cannot handle the response for the registration request. Instead of a proper JSON response it gets something like:According to the logs from the happy flow, it can be seen that there already is registration data on the client side (there is a call to get the client instance header, and then imminently a request to connect is executed), and therefore the registration request is not sent. Instead the connect request is executed as expected.
You mention that WebSEAL is used, and the provided information is not enough to understand why it is failing (it could be that for whatever reason WebSEAL is altering the request sent) - please provide the following:
I solved the issue whit acl make like this:
Now all work fine; only registration request endpoint is available for the unauthenticated users What do you think about this solution? Regards