Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.2
    • Fix Version/s: 2.2
    • Component/s: None
    • Labels:
      None

      Description

      Currently any state information stored on the server side (either with ServerSideStateHandling or tokens to prevent XSSF and replay attacks) are all stored on a per-session basis.

      Since multi-browser-tab editing becomes increasingly popular, we should provide a way to plugin a windowId mechanism.

      If the user currently opens an additional browser tab and clicks around in his application for a bit (I think in Mojarra and MyFaces the default is to store the 20 last views per session), and then goes back to the first browser tab, he will get a ViewExpiredException.

      Since doing the windowId handling inside the spec is pretty complicated (there is not yet a perfect solution without any downsides, see JAVASERVERFACES_SPEC_PUBLIC-949), we could leave this to the application and just use some provided windowId to keep the last n states for each browser tab.

      We would then have a MAX_VIEWS_PER_TAB and MAX_TABS_PER_SESSION limit.
      This is needed regardless if JAVASERVERFACES_SPEC_PUBLIC-949 is finally solved or not.

        Issue Links

          Activity

          Hide
          gerhard_petracek added a comment -

          JAVASERVERFACES_SPEC_PUBLIC-949 is just an umbrella-ticket. currently it isn't bound to a concrete approach. for sure we will need a pluggable mechanism e.g. inspired by the WindowHandler of myfaces codi

          Show
          gerhard_petracek added a comment - JAVASERVERFACES_SPEC_PUBLIC-949 is just an umbrella-ticket. currently it isn't bound to a concrete approach. for sure we will need a pluggable mechanism e.g. inspired by the WindowHandler of myfaces codi
          Hide
          lu4242 added a comment -

          I think it is worth to add some comments from myfaces mailing list. In MyFaces there is this issue:

          https://issues.apache.org/jira/browse/MYFACES-3404

          In few words, this concept becomes useful to fix server side state saving and flash scope. So, even if by default this is not implemented fully, at least the spec should provide an interface to delegate to other jsf libraries to implement this concept and let the logic so if this is provided the problems on server side state saving and flash scope could be handled in a "decoupled" way.

          From MyFaces dev list:

          Hi

          MS>> The ClientSideWindowHandler solution in CODI looks good so far, but there
          MS>> is still a lot to do.

          MS>> And like every technology, it has it's pros and cons...

          MS>> What do you think about making the windowId provider pluggable in MyFaces
          MS>> core first?

          I have been thinking about every possible option we have for implement this and
          the conclusion was the best way is make something like the hack done in CODI or
          a "variant" of it, like the one described on:

          http://wiki.apache.org/myfaces/Drafts/WindowId

          (Mixed approach of the first prototype)

          From the point of view of MyFaces Core, any solution should be bound to the
          renderkit in some way. So, windowId concept has sense to include it on the spec
          but its implementation should be done according to the renderkit. If the
          renderkit handles html, do the hack proposed but if is xml, do other thing
          and so on. It sounds like something to do outside MyFaces Core. Basically the
          problem is how to create an interface about something that could require
          changes over the renderkit/viewhandler?.

          Maybe we can minimize the problem, and provide an interface like this:

          public interface WindowIdRenderKitAware

          { public String getCurrentWindowId(FacesContext facesContext); }

          But let the details about how to "plug" all pieces inside CODI. MyFaces Core
          just offer the "integration point", and the default algorithm just do what is
          doing right now. Who should implement this interface? the renderkit, even if
          in the implementation the value can be stored inside FacesContext attribute
          map or request map. There exists a RenderKitWrapper interface, so it is
          easy to create a wrapper for default HTML_BASIC renderkit or any other and
          then scan through the wrappers and the first one implementing the interface
          will be the choosen.

          MS>> The REAL problem with JSF and multiple tabs is that once you open 2 tabs
          MS>> and click in 1 of them often enough, then you will destroy the state of
          MS>> the view in the other tab as well somewhen. Usually after 20 requests
          MS>> (default).

          There are two points where this logic could be useful inside MyFaces Core :

          1. Server side state
          2. Flash scope

          But in practice the only really relevant is 1. To implement 2. it is necessary
          a "requestId". MyFaces FlashImpl uses a counter and store its value inside
          a cookie. To fix this scope properly, the best is create a ExternalContext
          wrapper and provide and alternate Flash object, but that sounds like something
          that can be done outside MyFaces Core. If you are using CDI scopes, it sounds
          reasonable to provide an alternate Flash scope in CODI.

          If we can just modify the logic inside server side state to include "windowId"
          concept, it will be enough.

          MS>> To come over this, we need to store the n last views not only per session,
          MS>> but also per browser tab (==windowId).
          MS>> Of course, there can be lots of fancy stuff done to detect closed tabs,
          MS>> etc. But all this is much more stable if we really have the opportunity
          MS>> to distinguish between tabs. We can e.g. also introduce a configuration
          MS>> for maximum allowed tabs, to reduce memory blasting.

          Really since all state is stored in session, if the session is invalidated all
          tabs are removed from memory. Basically we already have params for max number
          of sessions and max number of logical sessions (which in fact can be seen
          as "tabs"). So what we have right now is ok, we just need to include windowId
          concept into the logic and that's it.

          MS>> All this is actually completely independent of how the windowId get's
          MS>> created and checked imo.

          Yes, that's right.

          MS>> I now tend to do the following (just atm creating a better playground
          MS>> example in CODI + hack on the ClientSideWindowHandler):
          MS>>
          MS>> a.) the cookie thingy is pretty bääh. it just doesn't work if a
          user clicks
          MS>> quickly through a list and opens lots of 'detail pages' on different tabs
          MS>> within 2 seconds.
          MS>>
          MS>> b.) it's currently a 'one or the other' thingy, and I now thought about
          MS>> combining the lazyWindowIdDropp.js and the current windowhandler.js
          MS>>
          MS>> My current research goes into the direction of
          MS>>
          MS>> 1.) always adding the windowId to each and every link and transport the
          MS>> windowId only via this parameter.
          MS>>
          MS>> 2.) For HTML5-browsers (detected via UserAgent) I render the
          MS>> windowhandler.html intermediate page which does all the fancy stuff of
          MS>> dynamically applying the old DOM on the intermediate page, etc. For other
          MS>> clients we rely on the lazyWindowId script.

          Ok, sounds promising. So, I'll focus on how to fix the logic for myfaces
          core server side state saving
          (org.apache.myfaces.renderkit.ServerSideStateCacheImpl), with the alternative
          proposed in this mail (WindowIdRenderKitAware interface, and then use a
          RenderKit wrapper).

          Show
          lu4242 added a comment - I think it is worth to add some comments from myfaces mailing list. In MyFaces there is this issue: https://issues.apache.org/jira/browse/MYFACES-3404 In few words, this concept becomes useful to fix server side state saving and flash scope. So, even if by default this is not implemented fully, at least the spec should provide an interface to delegate to other jsf libraries to implement this concept and let the logic so if this is provided the problems on server side state saving and flash scope could be handled in a "decoupled" way. From MyFaces dev list: Hi MS>> The ClientSideWindowHandler solution in CODI looks good so far, but there MS>> is still a lot to do. MS>> And like every technology, it has it's pros and cons... MS>> What do you think about making the windowId provider pluggable in MyFaces MS>> core first? I have been thinking about every possible option we have for implement this and the conclusion was the best way is make something like the hack done in CODI or a "variant" of it, like the one described on: http://wiki.apache.org/myfaces/Drafts/WindowId (Mixed approach of the first prototype) From the point of view of MyFaces Core, any solution should be bound to the renderkit in some way. So, windowId concept has sense to include it on the spec but its implementation should be done according to the renderkit. If the renderkit handles html, do the hack proposed but if is xml, do other thing and so on. It sounds like something to do outside MyFaces Core. Basically the problem is how to create an interface about something that could require changes over the renderkit/viewhandler?. Maybe we can minimize the problem, and provide an interface like this: public interface WindowIdRenderKitAware { public String getCurrentWindowId(FacesContext facesContext); } But let the details about how to "plug" all pieces inside CODI. MyFaces Core just offer the "integration point", and the default algorithm just do what is doing right now. Who should implement this interface? the renderkit, even if in the implementation the value can be stored inside FacesContext attribute map or request map. There exists a RenderKitWrapper interface, so it is easy to create a wrapper for default HTML_BASIC renderkit or any other and then scan through the wrappers and the first one implementing the interface will be the choosen. MS>> The REAL problem with JSF and multiple tabs is that once you open 2 tabs MS>> and click in 1 of them often enough, then you will destroy the state of MS>> the view in the other tab as well somewhen. Usually after 20 requests MS>> (default). There are two points where this logic could be useful inside MyFaces Core : 1. Server side state 2. Flash scope But in practice the only really relevant is 1. To implement 2. it is necessary a "requestId". MyFaces FlashImpl uses a counter and store its value inside a cookie. To fix this scope properly, the best is create a ExternalContext wrapper and provide and alternate Flash object, but that sounds like something that can be done outside MyFaces Core. If you are using CDI scopes, it sounds reasonable to provide an alternate Flash scope in CODI. If we can just modify the logic inside server side state to include "windowId" concept, it will be enough. MS>> To come over this, we need to store the n last views not only per session, MS>> but also per browser tab (==windowId). MS>> Of course, there can be lots of fancy stuff done to detect closed tabs, MS>> etc. But all this is much more stable if we really have the opportunity MS>> to distinguish between tabs. We can e.g. also introduce a configuration MS>> for maximum allowed tabs, to reduce memory blasting. Really since all state is stored in session, if the session is invalidated all tabs are removed from memory. Basically we already have params for max number of sessions and max number of logical sessions (which in fact can be seen as "tabs"). So what we have right now is ok, we just need to include windowId concept into the logic and that's it. MS>> All this is actually completely independent of how the windowId get's MS>> created and checked imo. Yes, that's right. MS>> I now tend to do the following (just atm creating a better playground MS>> example in CODI + hack on the ClientSideWindowHandler): MS>> MS>> a.) the cookie thingy is pretty bääh. it just doesn't work if a user clicks MS>> quickly through a list and opens lots of 'detail pages' on different tabs MS>> within 2 seconds. MS>> MS>> b.) it's currently a 'one or the other' thingy, and I now thought about MS>> combining the lazyWindowIdDropp.js and the current windowhandler.js MS>> MS>> My current research goes into the direction of MS>> MS>> 1.) always adding the windowId to each and every link and transport the MS>> windowId only via this parameter. MS>> MS>> 2.) For HTML5-browsers (detected via UserAgent) I render the MS>> windowhandler.html intermediate page which does all the fancy stuff of MS>> dynamically applying the old DOM on the intermediate page, etc. For other MS>> clients we rely on the lazyWindowId script. Ok, sounds promising. So, I'll focus on how to fix the logic for myfaces core server side state saving (org.apache.myfaces.renderkit.ServerSideStateCacheImpl), with the alternative proposed in this mail (WindowIdRenderKitAware interface, and then use a RenderKit wrapper).
          Hide
          Mark Struberg added a comment -

          txs Gerhard and Leo!

          Gerhard, you are right that this is actually a part of JAVASERVERFACES_SPEC_PUBLIC-949.
          Imo creating a way to plugin any windowId provider into JSF is necessary in any case, and it's easily doable by now.

          The reason I did split this one from the umbrella is because I fear that all ways to implement any windowId mechanism itself (the piece which detects and handles different browser tabs) all have certain side effects. I think we couldn't enable any one of those (nor a combined variant) for JSF by default - mainly because of compatibility reasons with older JSF versions.

          But we can easily add the support for pluggable windowId providers which a user must activate themselfs as a first step.

          If the one WindowHandler approach we currently work on in Apache MyFaces CODI proves itself usable, then we will definitely contribute it to the JSF spec!

          Show
          Mark Struberg added a comment - txs Gerhard and Leo! Gerhard, you are right that this is actually a part of JAVASERVERFACES_SPEC_PUBLIC-949 . Imo creating a way to plugin any windowId provider into JSF is necessary in any case, and it's easily doable by now. The reason I did split this one from the umbrella is because I fear that all ways to implement any windowId mechanism itself (the piece which detects and handles different browser tabs) all have certain side effects. I think we couldn't enable any one of those (nor a combined variant) for JSF by default - mainly because of compatibility reasons with older JSF versions. But we can easily add the support for pluggable windowId providers which a user must activate themselfs as a first step. If the one WindowHandler approach we currently work on in Apache MyFaces CODI proves itself usable, then we will definitely contribute it to the JSF spec!
          Hide
          gerhard_petracek added a comment -

          yes - as discussed several times, we can't enable it by default.
          all those details will be provided for the initial suggestion for JAVASERVERFACES_SPEC_PUBLIC-949.

          Show
          gerhard_petracek added a comment - yes - as discussed several times, we can't enable it by default. all those details will be provided for the initial suggestion for JAVASERVERFACES_SPEC_PUBLIC-949 .
          Hide
          Ed Burns added a comment -

          I assert that the design for ClientWindow does allow for plugability.

          Show
          Ed Burns added a comment - I assert that the design for ClientWindow does allow for plugability.
          Hide
          Manfred Riem added a comment -

          Closing resolved issue out

          Show
          Manfred Riem added a comment - Closing resolved issue out

            People

            • Assignee:
              Ed Burns
              Reporter:
              Mark Struberg
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: