How do backing bean scopes work? - ajax

I have some misunderstanding with JSF backing bean scope. I am new to JSF and now writing a simple project and all my beans mostly have session scope. But if my site will have many users that means my session will be very very big and kill my server. Some people have told me that the solution is use request scope beans. But, for example, when my page must be validated and if validation is failure show error messages and save all user input, what can I do in this situation? I am trying use component that use AJAX-request and hoped that my request bean will be not reconstructed, but this doesn't work (I am using <rich:datascroller> ).
I think I have big hole in my JSF understanding, I will be grateful if somebody explain what I must do in this situation or link me on some good article about bean scopes.

Scope defines the lifetime of the beans.
Request scope beans live during the servicing of one HTTP request, so thay are available both while you analyze the user's input and formulate the response page. So for simple validation and response I'd expect request-scoped beans to be what you need - the exception being perhaps if you send a redirect back to the browser and that submits a new request, then you may need ...
Session scoped beans live for the life of the user's session, ie. across several requests. Sessions might last for some time, but eventually the user logs out, or becomes quiscent and his session gets timed-out. So it doesn't matter how many users overall you have, just how many are active at once. It's pretty common to keep some session data around for each user (like at least who is, and perhaps his recently viewed stuff) so there's no fundamental reason to be worried by some data being kept. You just need to ensure you keep it tidy, don't keep the data for old pages very very long - perhaps just a "current data" bean or some such.

Related

How to use data saved from an old session in next session?

I have been using cookies to share non-sensitive data across sessions. I want to store some lastUsedEntity (a string literal) from the current session at user logout event so that that entity can be read/used at next login session. The said entity belongs to a session bean of my application.
I decided to extract and store this entity in #PreDestroy method of the session bean. The method ran successfully at session timeout of the application. But storing cookie failed because FacesContext.getCurrentInstance() was null in #PreDestroy method, maybe because JSF Lifecycle request-response cycle completed by then. I tried caching FacesContext.getCurrentInstance() in #PostContruct method of my session bean so that I could access faces context cached instance but then I faced another problem java.lang.IllegalStateException at com.sun.faces.context.FacesContextImpl.assertNotReleased because I used FacesContext as instance variable of my session scoped class. I would appreciate if I could get some heads up here or any other better idea in order to persist my old session data for further use in this scenario.
There's not necessarily means of a HTTP request when a HTTP session gets expired in server side due to enduser inactivity. The enduser itself is the only one who can send a HTTP request. If there's no HTTP request which invoked the FacesServlet, then there's no FacesContext either. Let alone a HTTP response on which you could return the cookie.
You'd better rethink your logic. E.g. set the cookie immediately on every request, overriding the previous one, if necessary on a specific path and/or with a timestamp in the cookie value. Depending on the concrete functional requirement there may be better ways though as cookies are fully manipulatable by the enduser and you should absolutely not depend critical business logic on that. If it's purely for presentation, it should be okayish, otherwise better store it in the database associated with logged-in user.

how to programmatically invalidate a session using spring security

Some users of my application can use it for a fixed maximum amount of time. At the first request happening past the expiration time, after checking the user is part of the target group, I want to invalidate the session, update the user and return a 401.
In theory a servlet filter invoked post-session-validation could be used for this. I am looking for pointers on how to do this using spring security.
Thanks!
While you could most certainly just add a normal servlet filter that executes at the very end of the chain (or at least after the Spring Security filter stack) where you get the SecurityContext and inspect the user (potentially logging out the user like this or this), I would suggest you instead simply change the session duration on per-user basis. After a successful login (AuthenticationSuccessHandler is a good place) you could simply call setMaxInactiveInterval on the session and give it a different value depending on the user's role. This seems a lot cleaner to me as you don't have to separately handle otherwise semantically equal actual and forced session expiration/logout cases.

rails session being reset intermittently

I know that this topic has been discussed a lot, but I believe that I've found a new variation of it: I have a Rails 4 application, which was upgraded from Rails 3, and which has the rails_ujs and csrf_meta_tags setup correctly.
Once the root_url is loaded in the browser, there is a javascript that fires a GET and a PUT, each one to its respective controller API in the application. By the moment those 2 API calls are fired, the session SHOULD have the _csrf_token there. And this is true, most of the times. Keep reading.
The problem is that, SOMETIMES, not always, we see some InvalidAuthenticityToken exceptions happening for the PUT request. (yes, I'm using protect_from_forgery :with => :exception on our API base controllers).
Analyzing the dump from exception_notification, I can see that the CSRF_TOKEN is setup correctly in the request header, but the most intriguing thing is that the session has only the session_id on it. Everything else is gone, including the _csrf_token.
Remember: this is happening intermittently! So I believe that it must be some kind of race condition.
This app is hosted on Heroku and running on Unicorn. I'm unable to reproduce the problem in my local environment. I've also read a lot of Rails code on github trying to understand the flows in which it resets the session, but I could not find the answer, since all CSRF protection is setup correctly and the problem happens intermittently.
It's also worth mentioning that we did not setup config.secret_key_base yet. But as this problem is happening intermittently, I don't think that this may be the root cause of it.
Also, I believe its worth mentioning that we have two controller hierarchies:
(1) all 'normal' application requests go through controllers which inherits from ApplicationController
(2) all API requests go through controllers which inherits from Api::BaseController, which inherits from ActionController::Base directly
I believe this controllers scheme is the most common for everybody...
The API endpoint for the GET request is rendering a json response. The API endpoint for the PUT request is returning head :ok.
Well, I would love if some Ruby on Rails expert could help on this.
Are you using the standard cookie-based session store? The cookie-based session store, last i looked, most definitely was subject to race-conditions, especially around AJAX requests -- and the race conditions were kind of an inherent part of the design of a cookie-based session store, with no real way to fix it.
This post from 2011 describes a cookie store race condition that also involves the authenticity token, and may be similar to yours. Their solution was turning off the CSRF protection, for certain actions anyway, which doesn't sound like a great solution to me.
This post from 2014 outlines race conditions with cookie session store, and suggests ActiveRecord or other server-side store as a solution. (As i write this, that URL is 404'ing, but available in google cache).
As you can see from the example, the session cookie is updated on every request, regardless of if the session was modified or not. Depending on when the response gets back to the client last, thats the cookie that will be used in the next call. For example, if in our previous example, if get_current_result’s response was slower than get_quiz, then our cookie would have the correct data and the next call to update_response would of work fine! So sometimes it will work and sometimes not all depending on the internet gods. This type of race condition is no fun to deal with.
The implications of this is that using cookie storage for sessions when you are doing multiple ajax call is just not safe. All information saved in the session might be wrong or nonexistent next time you check. So whats the solution?
...
A better solution would be to use a server side session store like active record or memcache. Doing so prevents the session data from being reliant on client side cookies. Session data no longer has to be passed between the client and the server which means no more potential race conditions when two ajax are simultaneously made!
I can't say for sure if you are running into that problem, but it would be worth a try to switch to the ActiveRecord cookie store, and see if your problem goes away.
Even the activerecord-based session store has at times in the past been subject to race conditions, I am not sure if the current implementation is, but they are at least conceivably solvable, whereas the race conditions in cookie-based store are fundamental.
The ActiveRecord store is probably subject to analagous race conditions to the cookie store actually -- IF you have more than one app process running (or a multi-threaded app server), so concurrent request handling is still possible, a very similar race condition is probably still possible. Although it should probably be even rarer than the race condition with the cookie store, and it is theoretically solvable, although perhaps with some domain-specific logic, unlike the race condition with the cookie store that is pretty much unsolvable if you are doing any async ajax.
For better format, write this as an answer, maybe it should be a comment though.
I met a similar problem, the root reason is my app called current_user before protect_from_forgery executed, this is current_user implementation in Devise:
def current_#{mapping}
#current_#{mapping} ||= warden.authenticate(scope: :#{mapping})
end
And Devise have a feature config.clean_up_csrf_token_on_authentication = true.
So the problem is, csrf token has been reset after current_user get invoked. because it calls warden.authenticate. Then when running protect_from_forgery. a csrf error has been raised. your session will be reset or an exception raised.
Hope this can help.

JSF - How to save managedBean state when session times out?

I am working for a client that has it's own session management system in case of idle timeouts. What happens is the following :
User stays idle for the set amount of time.
Session times out redirecting to login page
User enters credentials and is redirected back to where he was.
Now the above process is handled by passing a POST request passing the javax.faces.ViewState to the session management system. However, in case of timeouts it needs only 8K of data in the request to process and redirect. But since my managed bean is saving a lot of data (banking app, need to keep track of the calculations!) the size of the request is high (around 20K) due to which redirection fails.
So is there any way I can somehow save the ViewState? Or better, any way I can prevent the timeout? Something like keeping the session alive?
All my managed beans have a session scope.
EDIT: Just in case required, the javax.faces.STATE_SAVING_METHOD context-param in web.xml is set to client for performance purposes.
EDIT: Did a trace of the flow using HttpWatch and found out that javax.faces.ViewState is taking up 18kB of the total 22kB of size of the POST request. So my aim is narrowed down to reducing the size of ViewState. Any way to I can do this ?
State saving only keeps the data associated with the current view. Your problem here is that the session scoped beans are lost. I suggest two ways of solving the problem:
1) Implement a HttpSessionListener and in its sessionDestroyed() method get the beans, serialize them and store them in a database row associated with the current user. When the user logs in again you can fetch the beans, deserialize them and put them in the user's session.
2) Implement ajax poll that will ping the server in a specific period and this way the session will not timetout. You could achive this using Richfaces JSF library that has a built-in JSF component for ajax poll.

At what point should I change the way Struts acquires the session token?

It seems I have to find a different way to transmit the session token from a Flex client to a Struts backend without using cookies.
If I were to put the session token in the payload of a request, at what point would I have to customize Struts' behaviour so that I can reuse as much of the existing session handling as possible? In particular, I don't want to reimplement whatever security measures (such as tying a token to an IP) and configuration parameters (such as session expiration interval).
There's a CreateSession interceptor, rather early in the default stack, should I swap that with a subclassed version?
I'm not very experienced with Flex but as this seemed interesting and I do not like to see questions go unanswered I thought I would have a stab at it. As I understand it the Flex session (HttpFlexSession) and the HttpSession are completely separate entities. That said you should be able to share data between them.
There is a very relevant free chapter (Chapter 20: Flex Integration with J2EE) available from the book "Developing Rich Clients with Macromedia Flex" by Steven Webster and Alistair McLeod.
I will now quote heavily from that free chapter! Of particular note:
Maintaining State
The biggest leap in understanding to
be made is that there's no longer a
need for HTTP session state. Although
your requests between rich client and
server are ultimately being made over
HTTP, HTTP has been reduced to a
transport technology instead of a
technology that we need to integrate
with. J2EE developers are comfortable
with the concept of placing attributes
and parameters in the HTTP request and
response objects, and maintaining
state by storing objects in the HTTP
session. ...
... Flex can in fact offer access to
the HTTP session and allow the Flex
client to treat the HTTP session as
"just another object on the server."
However, in our experience, using the
HTTP session should be a "bad smell"
that identifes a refactoring
opportunity to shift some of your
application state onto the client.
Later on in this chapter it shows you how to configure the session object for Flex client access.
Gaining Access to J2EE Sessions
Flex preconfigures a session servlet
in the default web.xml file, which
makes available a server-side Java
object that can be used to access and
modify the J2EE session for an
application. By placing one of the
following Remote object definitions in
our Service Locator at services.mxml,
we make available to our application a
service that can get and set objects
in the J2EE session, as well as remove
objects from the session:
<mx:Remote object source="servlet" id="sessionObject" />
<mx:Remote object source="#ContextRoot()" id="sessionObject"/>
As with any other <mx:RemoteObject>
tag, the session service can use
result and fault event handlers to
handle requests to fetch items from
the session. The web.xml descriptor
defines the name of the session
servlet as servlet; therefore, we use
one of the following examples to work
with the J2EE session:
sessionObject.session( "set","customerID", 700 );
sessionObject.session( "get", "customerID" );
sessionObject.session("remove", "customerID" );
These three examples demonstrate how
the session service is used to get,
set, or remove items in the J2EE
session from a Flex client.
So it would seem that although you can share session data between Flex and backend Java, however, the suggestion seems to be that this is an anti-pattern.
With respect to security measures, if you were using Servlet Filters to implement IP restriction then your security could be applied to all the resources in your web application (irrespective of whether it was of Struts or Flex origin).

Resources