Worklight 6.1 :How to clear session on worklight server at adapter level - ibm-mobilefirst

I am handling session on server side and i am able to manage that by using adapter side code
var cookie = WL.Server.getClientRequest().getHeader('Cookie');
var request = WL.Server.getClientRequest();
var session = request.getSession();
var sessionid = session.getId();
But the problem is every time i am hitting the adapter i am getting the same session on server side.
How to kill that session on adapter side so that i can create new session every time i hit the adapter.
I tried session.invalidate() but no use for me. After doing this also i am getting the same session on server side.
Please suggest what need to be done on server side or adapter side.

What you're describing is a default WL server behaviour. You'll get a new session created first time you hit the server and this session will be reused till it times out.

It will help greatly if you will explain exactly what you want to achieve. As it is, you are not explaining it clearly enough.
If you're talking about the server between the Worklight Server and the backend, then:
To get a new session with every adapter request sent to the backend, you need to set the connectAs property to endUser on the relevant procedure:
<procedure name="getStories" connectAs="endUser"/>
Refer to the following blog post which explains it at length:
Configuring HTTP adapters for stateless/stateful backend connectivity and user identity propagation
If you're actually talking about the session creating when invoking the adapter on the client-side, then you cannot invalidate the session on the adapter-level. The only way to get a new session would be to re-open the application (assuming the session has already expired between the client and the Worklight Server, you'll then get a new session).

Related

ASP.NET Core WEB API self-connection through external URL "No connection could be made because the target machine actively refused it"

I have multitenant Web API application with Hangfire scheduler that calls a task which trying to connect to self endpoint through external server DNS name with tenant name in it. Doing it this way, because Hangfire doesn't have HttpContext to resolve on which tenant task must shoot. On my staging server or if I send this request from Postman it works nice, but on my local machine and on production server it raises the error from title.
The code looks like nothing special:
var url = $"{tenant.Url}/notifications/client/send-appointment-sms";
var jwtToken = await _authService.GetTokenByUsername("admin");
using var requestMessage = new HttpRequestMessage(HttpMethod.Get, url);
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", jwtToken.AccessToken);
var response = await _httpClient.SendAsync(requestMessage);
Where tenant.Url is for example https://api.tenant1.example.com/api2 which is available from browser on production server where application is running.
If I understanding clearly, my application can not connect to itself for some reason.
I have tried common solutions like firewall settings or disable proxy, still nothing on this point. What can I check next?
UPD I must add that NodeJS server on production is able to call this service too, so I think issue is not in server but maybe more about ASP.NET configuration settings.

How do I capture the Worklight defaultOptions:onFailure event?

I have a Worklight 6.1.0.1 hybrid app that I'm running on iOS. The app uses adapter-based authentication. The app prepares the invocation data makes the following call when the Login button is clicked:
singleStepAuthRealmChallengeHandler.submitAdapterAuthentication(invocationData, {});
If the WL service is down, or if the mobile device has no network access, the invocation will timeout. I see the following in the Xcode console:
defaultOptions:onFailure Request timed out for http://myipaddress:10080/myapp/apps/services/../../invoke. Make sure the host address is available to the application (especially relevant for Android and iPhone apps).
How can I capture this timeout event, so that I can update the UI with a proper message?
Update May 23rd based on comments:
What is your exact flow?
You should first use WL.Client.connect({onSuccess: ..., onFailure:...});
If connection to the server is successful, you will enter the challenge handler. Otherwise, you will enter onFailure and there you can create the custom error handling.
Previous answer attempt:
The below is when trying to connect() to the Worklight Server.
If you want custom handling for when the client fails connecting to the server I believe you need to enable and use the option onConnectionFailure in initOptions.js:
var wlInitOptions =
// # The callback function to invoke in case application fails to connect to Worklight Server
//onConnectionFailure: function (){},
}
Otherwise, Worklight's default dialog will be displayed.

Automatically relogging in to a realm after connection loss in IBM Worklight

My problem is as follows :
I have an application protected by a mobile security test involving a LDAP server. The corresponding realm is called LDAPrealm. I use the form-based authenticator + custom LDAP login module.
When the connection to the worklight server is lost and then re-established, I see that the current user is not authenticated in the LDAP realm anymore.
What I want is be able to re authenticate the user without having him enter credentials again.
However, since the user is still authenticated for other realms included by default in the mobile security test, the worklight server does not challenge the client again for credentials, which is causing j_security_check error when trying to submit credentials.
As a side note those credentials are stored in the encrypted json store for offline authentication and use of the app.
So my question is :
Is it possible to force the server to challenge the client again for this LDAPrealm and use submitLoginForm to re-log in?
More generally, is there a way to clear a user+device from all realms before trying to log in again?
Edit reasons : previous error was caused by a typo
In the case where the user first logs in online then loses connection then get connection again, calling
WL.Client.logout("LDAPRealm",{onSuccess:stealthed_relog});
and calling WL.Client.connect() later in stealthed_relog before sending credentials seems to wield the desired behaviour.
However, when the user logs in offline and then gets connection, when I try to use WL.Client.connect(), it says another instance of WL.Client.connect has already been called.
edit : for the log offline case, the application get challenged automatically shortly after that the connected event fires (cause of heartbeat? I do not really know), so you just have to use
login_clientside.submitLoginForm();
to successfully log in again.
If someone has a better way to implement auto-reconnecting in worklight with ldap server, feel free to post it and I'll unaccept my answer.

IBM Worklight v5.0.5 - Encrypted Offline Cache not working in Android or iOS

While debugging, we observe following behavior:
1) When trying to get encryption key from server then error on both (iOS or Android) platform
response [https://xxxx.xxxx.com:443/worklight/apps/services/random]
success: Exception thrown by application class
'com.ibm.ws.webcontainer.session.impl.HttpSessionContextImpl.checkSecurity():685'
SESN0008E: A user authenticated as anonymous has
attempted to access a session owned by user:NewRealm/CN=test
user,OU=Temporary Users,OU=Acc,DC=xxxx,DC=com.
2) When trying to read a stored value error on android is [Logcat]
Android Message: Uncaught 9 at
file:///data/data/com.xxxx.xxxxapp/files/www/default/wlclient/js/encryptedcache.js:63
Where try to call WL.EncryptedCache.read
Worklight version used is 5.0.5 Consumer Edition (with Oracle 11i) on
Windows 2008 R2
WebSphere Liberty profile
Worklight server is sitting behind IBM Datapower XI52. All SSL calls to the server are going via DP.
Authenticator - WebSphereFormBasedAuthenticator & LoginModule - WASLTPAModule
The following is not really an answer, since I'm not familiar with authentication (LTPA, FormBasedAuth, Data Power, etc.)... just a couple of comments that could help you debug/isolate the issue.
Looks like a problem with authentication:
A user authenticated as anonymous has attempted to access a session
owned by user:NewRealm/CN=test user,OU=Temporary
Users,OU=Acc,DC=xxxx,DC=com.
Not with the Encrypted Offline Cache (EOC).
EOC will try to get a random token calling the following function:
WL.EncryptedCache.secureRandom(function (data) {
console.log(data);
});
It should output something like this:
response [/apps/services/random] success: 9053bdcfd902aac3dfb59a9874c9cf55223b7d17
9053bdcfd902aac3dfb59a9874c9cf55223b7d17
You can view the functions source code typing the following in a JS console:
WL.EncryptedCache.secureRandom
If you're using Google Chrome developer tools there's a checkbox for Log XMLHttpRequests when you click on the gear icon > General > Console.
You can also try to request the URL directly. Assuming the host is localhost, port is 10080 and project name is wlproj:
http://localhost:10080/wlproj/apps/services/random
9053bdcfd902aac3dfb59a9874c9cf55223b7d17
You can view HTTP traffic with Wireshark or Charles Proxy.
I imagine this will fix the EOC issue for you, if you don't mind generating the random token locally (less security, AFAIK):
WL.EncryptedCache.secureRandom = function(callback){callback(Math.random()+"")}
For example:
Notice it never goes to the server, everything is done locally.
A user authenticated as anonymous has attempted to access a session owned by user:NewRealm/CN=test user,OU=Temporary Users,OU=Acc,DC=xxxx,DC=com.
This usually means that there is a conflict with the session sent by the user (the session cookie) belongs to a user (in this case), but the LTPA token sent as a cookie was not sent or was not valid. There could be a few causes of this. This best way is to do a trace between datapower and the worklight server to make sure an LTPA token is even being sent to the worklight server. If it is, verify all of the LTPA requirements are met (synchronized time, same private key on both machines).

spring security jmx authneticator

I have a JMX server configured without Spring and am trying to implement Spring Security for the Authorization part.
(See here, https://blogs.oracle.com/lmalventosa/entry/jmx_authentication_authorization
Use Case 4, without the Authorization part)
I would like now to implement the Authorization part using Spring Security.
In my JMX authenticator, I do:
final List<GrantedAuthority> roles = new ArrayList<GrantedAuthority>();
roles.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
final Authentication auth = new UsernamePasswordAuthenticationToken(credentialsArr[0], credentialsArr[1],
roles);
SecurityContextHolder.getContext().setAuthentication(auth);
And in the MBeans I try to fetch it and see that it has been passed correctly (in the future I plan to add Spring Annotations to check for roles, for method invocation).
final Authentication springAuth = SecurityContextHolder.getContext().getAuthentication();
The problem is, that in the standard connection flow:
JMXServiceURL url = ...;
Map env = ...;
String[] creds = {"monitorRole", "mrpasswd", "FileRealm"};
env.put(JMXConnector.CREDENTIALS, creds);
JMXConnector cc = JMXConnectorFactory.connect(url, env);
MBeanServerConnection mbsc = cc.getMBeanServerConnection();
I get a JMX connector, then connect to the MBean server and invoke a method - it works.
I get through the authenticator, set the Spring Context and get it in the Mbean.
But when I connect using a Jconsole, for example, I don't get the Spring Context in the Mbean.
I am using the Inheritable Thread strategy.
Is there a way to get the context also in the MBean, when connecting using the JConsole and other connectors?
If I implement JMX using Spring, will it help me to solve the problem?
Is my main flow fool proof (is there a chance I will not get the Context in the MBean)? I am asking this, since this flow is critical to me, to be fool proof.
Thanks a lot!
I will answer my own question, as I've seen interest in it and wanted to share my own conclusions (unrelated to the numbers above):
It looks like connecting with JConsole(or JVisualVM) locally (i.e. to localhost) connects directly to the thread, without going through the JMX Authenticator.
The only workaround I found was by connecting with a full URL (e.g. service:jmx:rmi:///jndi/rmi://10.45.32.112:3251/jmxrmi).
One mechanism that works always is the Java Security context; when JMXAuthenticator returns a Subject, you may assign the Spring Security Context to it and thus surely get it when invoking the method (e.g. in an Advice running before the invocation).
See this reply I got:
http://forum.springsource.org/showthread.php?134327-JMX-Authentication-with-Spring-Security-%283-1-x%29
I can't say for sure if the flow mentioned in the question is fool proof.
But it seems like it is, based on this assumption:
If you create a new connection for each JMX call and use it only for one invocation, you will get the Spring Security Context to propagate correctly.
Hope it helped you people :-)