I am extending an application (Jasig CAS) built using Spring Webflow 2.4.1 and Spring 4.1.8. I have noticed that when I walk away for a while and come back, the flow will continue executing. It does not timeout.
I thought that after idle timeout, the flow will take user back to the starting point since the session is destroyed, the flow execution key would be lost and so are the variables stored in HTTP session. But, apparently that is not the case.
Can someone help me understand why the flow does not timeout? And, how did it get the flow execution key and flow variables after the HTTP session is destroyed?
Here is the log I see. Note that the flow is resuming and flow variables restored, that maybe why the flow can continue running.
2016-07-26 16:10:17,688 DEBUG [org.springframework.webflow.mvc.servlet.FlowHandlerMapping] - Mapping request with URI '/cas/login' to flow with id 'login'
2016-07-26 16:10:17,689 DEBUG [org.springframework.webflow.executor.FlowExecutorImpl] - Resuming flow execution with key 'c5317d47-5330-4189-971f-......(key omitted)
2016-07-26 16:10:17,710 DEBUG [org.springframework.webflow.definition.registry.FlowDefinitionRegistryImpl] - Getting FlowDefinition with id 'login'
2016-07-26 16:10:17,710 DEBUG [org.springframework.webflow.engine.impl.FlowExecutionImpl] - Resuming in org.springframework.webflow.mvc.servlet.MvcExternalContext#61b71149
2016-07-26 16:10:17,710 DEBUG [org.springframework.webflow.engine.Flow] - Restoring [FlowVariable#1a5e084e name = 'credential', valueFactory = [BeanFactoryVariableValueFactory#13734668 type = UsernamePasswordCredential]]
2016-07-26 16:10:17,711 DEBUG [org.springframework.webflow.engine.Flow] - Restoring [FlowVariable#4cae64b7 name = 'changePassword', valueFactory = [BeanFactoryVariableValueFactory#4d5651b5 type = ChangePasswordCredential]]
2016-07-26 16:10:17,711 DEBUG [org.springframework.webflow.engine.Flow] - Restoring [FlowVariable#fe3958d name = 'changeEmail', valueFactory = [BeanFactoryVariableValueFactory#266f6421 type = ChangeEmailAddress]]
2016-07-26 16:10:17,711 DEBUG [org.springframework.webflow.engine.Flow] - Restoring [FlowVariable#7c53be39 name = 'changeSecretQuestion', valueFactory = [BeanFactoryVariableValueFactory#5dedcff3 type = ChangeSecretQuestion]]
2016-07-26 16:10:17,712 DEBUG [org.springframework.webflow.mvc.view.AbstractMvcView] - Processing user event 'submit'
Either your Session isn't actually destroyed or this Jasig CAS does something non-default in order to make Flows persist beyond the HTTP Session. The Spring Web Flow defaults do use the Session and will not be able to resume once the Session expires.
Related
I'm using Firebase Auth to have users authenticate using their Google Account. I found the token returned by firebase.auth().currentUser.getIdToken is only valid for 1 hour. To allow the session to last longer I tried creating a session cookie as outlined in Manage Session Cookies:
const expiresIn = 60 * 60 * 24 * 5 * 1000;
admin.auth().createSessionCookie(idToken, {expiresIn}).then((sessionCookie) => {
const options = {maxAge: expiresIn, httpOnly: true, secure: true};
res.cookie('session', sessionCookie, options);
res.end(JSON.stringify({status: 'success'});
}
This code successfully created a session cookie and subsequent requests could be verified using admin.auth().verifySessionCookie. All was well until I tried increasing the expiresIn duration. It turns out that Firebase session cookies have a maximum expiration time of 2 weeks. From the docs:
Ability to create session cookies with custom expiration times ranging from 5 minutes to 2 weeks.
For this project I would prefer to have a user log in once and stay logged in. I tried extending the session on every interaction with the server but I didn't find any official documentation on how to do that. It seemed to make sense to call admin.auth().createSessionCookie on the server using the token returned by admin.auth().verifySessionCookie, but that failed with this error:
Failed to extend session: { Error: An internal error has occurred. Raw server response: "{"error":{"code":400,"message":"Invalid value at 'valid_duration' (TYPE_INT64), 604.8","errors":[{"message":"Invalid value at 'valid_duration' (TYPE_INT64), 604.8","domain":"global","reason":"badRequest"}],"status":"INVALID_ARGUMENT"}}"`enter code here`
at FirebaseAuthError.Error (native)
at FirebaseAuthError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:39:28)
at FirebaseAuthError.PrefixedFirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:85:28)
at new FirebaseAuthError (/user_code/node_modules/firebase-admin/lib/utils/error.js:143:16)
at Function.FirebaseAuthError.fromServerError (/user_code/node_modules/firebase-admin/lib/utils/error.js:173:16)
at /user_code/node_modules/firebase-admin/lib/auth/auth-api-request.js:726:49
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
errorInfo:
{ code: 'auth/internal-error',
message: 'An internal error has occurred. Raw server response: "{"error":{"code":400,"message":"Invalid value at \'valid_duration\' (TYPE_INT64), 604.8","errors":[{"message":"Invalid value at \'valid_duration\' (TYPE_INT64), 604.8","domain":"global","reason":"badRequest"}],"status":"INVALID_ARGUMENT"}}"' },
codePrefix: 'auth' }
Is it possible to extend Firebase sessions on the server side without requiring the client to do any work? Is it possible to use Firebase auth with tokens with a longer lifespan than 2 weeks? If not, in there a standard approach on how to achieve incredibly long lived sessions?
Extending it too long can be risky, as if the cookie is leaked, the window of attack will be quite wide. I don't recommend extending the session longer but if this is a requirement, you could try to do the following:
after verifying the session cookie on your server for the user and noticing it is about to expire.
mint a custom token for that user ID with Admin SDK
signInWithCustomToken with that custom token.
user.getIdToken() to get new ID token.
Exchange that ID token for a new session cookie.
The downside is that the claims in the session cookie will correspond to a custom token user.
Notice for client side sessions, the ID token passed around has one hour duration, even though the session is indefinite. This is because a refresh token lives on the device and is used to exchange new ID tokens. At any time, only the ID token is transmitted limiting the window of attack to one hour if that token is leaked.
I think it would be useful for Firebase Auth to offer an active duration functionality. That would be better for extending sessions continuously in short increments. This would be better than minting an indefinite or very long cookie. An active user would constantly have their session extended. This is not offered by Firebase Auth but you can file a feature request for it.
In my JxBrowser Application I create and dispose a browser for each request based on given needs. After several hundred requests, I begin to received a "Failed to get Browser browserChannel" exception. In an attempt to debug this, I noticed that I have an ever growing number of ChannelListeners. I added the following code to my application after the browser.dispose() to see this.
if (CollectionUtils.isNotEmpty(IPC.getDefault().getMainChannel().getChannelListeners())) {
List<ChannelListener> channelListeners = IPC.getDefault().getMainChannel().getChannelListeners();
for(ChannelListener listener : channelListeners) {
logger.info("Listener: " + listener.getClass());
}
}
I see these 4 repeat in my logs as a result
2018-06-21 13:30:28,105 [pool-3-thread-1] INFO c.t.l.l.a.service.BrowserManager - Listener: class com.teamdev.jxbrowser.chromium.ZoomService$a
2018-06-21 13:30:28,105 [pool-3-thread-1] INFO c.t.l.l.a.service.BrowserManager - Listener: class com.teamdev.jxbrowser.chromium.NetworkService$a
2018-06-21 13:30:28,105 [pool-3-thread-1] INFO c.t.l.l.a.service.BrowserManager - Listner: class com.teamdev.jxbrowser.chromium.NotificationService$a
2018-06-21 13:30:28,105 [pool-3-thread-1] INFO c.t.l.l.a.service.BrowserManager - Listener: class com.teamdev.jxbrowser.chromium.ProtocolService$a
Is this there something I'm not disposing correctly? Is this a JxBrowser issue, maybe related to my IPCException?
These 4 listeners belong to the default IPC instance that is implemented as a singleton. So, once you access the default IPC instance through the IPC.getDefault(), these 4 listeners are registered and we never unregister them.
FYI: the library might create a lot of ChannelListeners inside. These listeners are part of the internal private logic. They are removed when it's necessary.
As for the "Failed to get Browser browserChannel" error message – this error message indicates that the library failed to initialize the Browser instance. In this case the log messages should be analyzed to detect the root cause of the issue.
I want to turn off the logging of the following (lifecycle?) events, which configuration directive controls this?
DEBUG [akka://MyActorSystem/system/IO-TCP/selectors/$a/371] - started (akka.io.TcpOutgoingConnection#558309d8)
DEBUG [akka://MyActorSystem/system/IO-TCP/selectors/$a/371] - now watched by Actor[akka://MyActorSystem/system/IO-TCP/selectors/$a#
DEBUG [akka://MyActorSystem/system/IO-TCP/selectors/$a/371] - Attemptingconnection to [localhost/127.0.0.1:12002]
DEBUG [akka://MyActorSystem/system/IO-TCP/selectors/$a/371] - Connection established to [localhost/127.0.0.1:12002]
DEBUG [akka://MyActorSystem/system/IO-TCP/selectors/$a/371] - stopped
You can disable the lifecycle log messages ("started", "watched", "stopped") with the following setting in application.conf:
akka {
actor {
debug {
# disable DEBUG logging of actor lifecycle changes
lifecycle = off
}
}
}
If you're using remoting:
akka {
remote {
log-remote-lifecycle-events = off
}
}
The TCP connection log messages in your excerpt (which are set here and here) are hard-coded at the debug level and, unlike the lifecycle events, cannot be disabled. To prevent the logging of these messages, set your global logging level to a level that is more coarse-grained than debug (doing this also prevents the logging of lifecycle events, regardless of the above settings). More information on logging is found in the official documentation.
We are seeing a very strange problem with an ASP.NET application that was recently upgraded to NHibernate 3.10GA, Castle 2.5.2, and using Castle.Facilities.NHibernateIntegration. We are using ISessionManager from NHibernateIntegration with the Web.SessionWebModule component to manage our request response loop, and have it configured with isWeb=true.
Our application returns a page for a url encoded parameter, and this page also subsequently makes some web-service calls.
The problem happens very intermittently, and manifests itself as a NHibernate.LazyInitializationException - Could not initialize proxy - no Session error, caused by the lazy-loading of a many-to-one relationship from the main object. This would suggest that the session object is being lost while in the request-response loop for the page.
We decided to debug the OnBeginRequest and OnEndRequest methods in Castle.Facilities.NHibernation, and added some debugging statements to identify the thread. What we found is the following:
In the cases where there is an error, the threadId in the OnBeginRequest does not match the threadId in the OnEndRequest; and further it appears that the original thread is being used for other requests and responses. When the initial page request is finally returned it's threadid doesn't match the original threadid it was started in. Has anyone seen anything like this?
Here's the debug data. Note the [9] indicates the originating thread according to log4net
[9] DEBUG SessionWebModule - On begin request thread id: 9 for MyPage.aspx
[9] DEBUG SessionWebModule - On begin request thread id: 9 for example.ashx
[9] DEBUG SessionWebModule - On end request thread id: 9 example.ashx
[9] DEBUG SessionWebModule - On begin request thread id: 9 for WebService.asmx/js
[9] DEBUG SessionWebModule - On end request thread id: 9 for WebService.asmx/js
[6] ERROR NHibernate.LazyInitializationException - [error message describing relationship] -Could not initialize proxy - no Session.
[6] DEBUG SessionWebModule - On end request thread id: 9 for MyPage.aspx
Note the first and last line showing that the page request originated in thread 9, but returned in thread 6.
I beleive you are on IIS 7 and asp.net 2.0 ?
If yes , please try to set MaxConcurrentRequestsPerCPU
http://blogs.msdn.com/b/tmarq/archive/2007/07/21/asp-net-thread-usage-on-iis-7-0-and-6-0.aspx
Has anyone suddenly encountered login errors from their users trying to connect to salesforce.com from a Flex app using as3salesforce.swc?
I get the following error... password removed to protect the innocent...
App Domain = null
Api Server name = na3.salesforce.com
_internalServerUrl = https://na3.salesforce.com/services/Soap/u/14.0
loading the policy file: https://na3.salesforce.com/services/Soap/cross-domain.xml
Your application must be running on a https server in order to use https to communicate with salesforce.com!
login with creds
loading the policy file: https://na3.salesforce.com/services/crossdomain.xml
Your application must be running on a https server in order to use https to communicate with salesforce.com!
invoke login
intServerUrl is null
intServerUrl = https://na3.salesforce.com/services/Soap/u/14.0
_invoke login
'5A5D3012-7717-E3C2-9B39-FFBBFF1F1B47' producer set destination to 'DefaultHTTPS'.
Method name is: login
'direct_http_channel' channel endpoint set to http://localhost/pm_server/pm/
'5A5D3012-7717-E3C2-9B39-FFBBFF1F1B47' producer sending message 'E32C7199-72C1-B258-B483-FFBC1641173D'
'direct_http_channel' channel sending message:
(mx.messaging.messages::HTTPRequestMessage)#0
body = "<se:Envelope xmlns:se="http://schemas.xmlsoap.org/soap/envelope/"><se:Header xmlns:sfns="urn:partner.soap.sforce.com"/><se:Body><login xmlns="urn:partner.soap.sforce.com" xmlns:ns1="sobject.partner.soap.sforce.com"><username>simon.palmer#dialectyx.com</username><password>******</password></login></se:Body></se:Envelope>"
clientId = (null)
contentType = "text/xml; charset=UTF-8"
destination = "DefaultHTTPS"
headers = (Object)#1
httpHeaders = (Object)#2
Accept = "text/xml"
SOAPAction = """"
X-Salesforce-No-500-SC = "true"
messageId = "E32C7199-72C1-B258-B483-FFBC1641173D"
method = "POST"
recordHeaders = false
timestamp = 0
timeToLive = 0
url = "https://na3.salesforce.com/services/Soap/u/14.0"
'5A5D3012-7717-E3C2-9B39-FFBBFF1F1B47' producer connected.
Method name is: login
Error: Ignoring policy file at https://na3.salesforce.com/crossdomain.xml due to meta-policy 'by-content-type'.
'5A5D3012-7717-E3C2-9B39-FFBBFF1F1B47' producer acknowledge of 'E32C7199-72C1-B258-B483-FFBC1641173D'.
responseType: Fault
Saleforce Soap Fault: sf:INVALID_LOGIN
INVALID_LOGIN: Invalid username, password, security token; or user locked out.
Comunication Error : sf:INVALID_LOGIN : INVALID_LOGIN: Invalid username, password, security token; or user locked out. : [object Object]
Obviously nobody else out there is building Flex apps on top of salesforce.com..
yippee, I'm first.
Anyhow, I just found out that this is a bug at salesforce.com as at 6th December 2008. The issue is that the scripts which handle login do not cope adequately with the redirect necessary because of load balancing on the salesforce.com servers.
It should be possible to go through the www front door of salesforce.com's api with a URL such as...
"https://www.salesforce.com/services/Soap/u/13.0";
where the 13 represents the version of their API you are targetting. However, all users are actually assigned to a specific server, so the front door should redirect the login request to the approriate place, and it doesn't if you are coming from Flex.
A workround is to specify your server in the URL, such as...
"https://na5.salesforce.com/services/Soap/u/13.0";
...which is what I was doing. That's fine if you are a single user accessing the same resources continually and your account remains attached to that server. However if...
You are distributing your app so anyone who has a salesforce.com enterprise account can log in OR
Your account gets moved because of some internal load balancing (which is what happened to me)
then the approach of providing a fixed server won't work.
The bug (as far as I understand it) is that the www route doesn't adequately redirect to your host server. Last intelligence was that it will be fixed "soon".
I wish I could mark this as the answer...