You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Jerry Malcolm <te...@malcolms.com> on 2019/04/11 23:34:08 UTC

Re: Session Persistence Problems -- Epilog

On 4/11/2019 5:05 PM, Jerry Malcolm wrote:
> On 4/11/2019 4:22 PM, Christopher Schultz wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA256
>>
>> Jerry,
>>
>> On 4/11/19 15:29, Jerry Malcolm wrote:
>>> Alternatively, if I had a better understanding of how sessions are
>>> managed by both TC and the browser, it might help me figure out
>>> what is going wrong.  I know a session key is generated by TC and
>>> sent back in a response.  And I'm assuming that the browser must
>>> return that session key on subsequent calls.  But if there are
>>> several webapps on domain, how does the browser differentiate which
>>> session key to send back on a subsequent response?  Is it just
>>> understood that the first 'folder' level under the domain (i.e.
>>> context name) is always a different session key?
>>> (myDomain.com/order vs. myDomain/account)?   Or does the browser
>>> send all session keys back per domain and let TC figure out which
>>> one, if any, to use?   Again, just looking for a little education
>>> here....
>> Do you know if HTTP cookies or URL-parameters are being used for
>> session-management? If you aren't sure, try logging-in to your
>> application and look at the URLs and cookies.
>>
>> Typically, a web application will use cookies with the name
>> JSESSIONID. If the session identifier is tracked in the URL, then
>> you'll see ";jsessionid=[id]" in your URLs after the path but before
>> the query string.
>>
>> It's very easy to "lose" a URL-tracked session id because every single
>> URL generated by your application must include that parameter. A sinle
>> miss can cause the session to be lost by the client. If you are using
>> SSO (always with a cookie), it can mask the dropping of the session in
>> this way.
>>
>> It's harder to "lose" a session cookie since the browser typically
>> manages that. Cookies are tracked per web-application using each
>> application's path. The browser should only return a single cookie for
>> a given path. If you have applications that share a URL space (e.g.
>> /master and /master/sub and /master/sub2) then things can get very
>> confusing for the browser and the server. It's best not to overlap
>> URL-spaces in this way.
>>
>> Are you using clustering or anything else like that which might also
>> cause session-ids to change?
>>
>> - -chris
>
> Thank you so much for the info... I think we're getting somewhere.... 
> I am definitely using cookies and not url parms for the session id. 
> (no clustering).  I went into the firefox debugger and located the 
> cookie storage for the site.  I found a cookie for each webapp context 
> that I am using.  That makes sense.   I think I know what is 
> happening.  Correct my assumptions here:
>
> I have a webapp with context /order.  There is a JSESSIONID cookie for 
> /order as expected. I assume that every time I send a URL from the 
> browser with the /order context, the browser will correctly send the 
> /order session cookie.  So far, so good...
>
> But.... I have a rewrite rule "/storefront" that maps to one of the 
> /order urls.  I assume the browser knows nothing about rewrites, so 
> the browser is going to assume that "/storefront" is simply a 
> different webapp context that it doesn't have a session id cookie for, 
> and therefore doesn't send anything.  Therefore, when the rewritten 
> url becomes another /order url, TC gets an /order request but with no 
> session id, and therefore creates a new session and sends it back for 
> the browser to store (replace) as the /order session id.
>
> So assuming I have analyzed this correctly, that can explain precisely 
> what I'm seeing.   Understanding the problem is a big step... But now 
> I have to figure out how to get around it and make it do what I want.  
> At this point, I see three options:
>
> 1) remove all rewrites from httpd.  That is going to be massive, very 
> difficult, and non-trivial.  And I'll also have to come up with way to 
> handle multi-client variations, etc. that I have been mapping by 
> simply using different rewrites on each site.  This one is not even 
> close to my first choice....
>
> 2) Could I perhaps send my own additional JSESSIONID cookies with the 
> current "/order" session id for the rewrite 'fake contexts' such as 
> "/storefront" so that the browser will basically send a copy of the 
> /order session id with the /storefront url?
>
> 3) I really don't care to have separate sessions for each webapp 
> context anyway.  In fact, I'd prefer it if there was one session / 
> sessionId for the enter application (all 10 contexts).  Is there any 
> way to send the session id cookie keyed as simply "/" instead of 
> "/<context>"?  All URLs to the domain whether rewrite aliases or 
> actually urls would match this one JSESSIONID cookie and therefore 
> would always send the JSESSIONID.  If that would work, that would 
> solve everything and all rewrites would still work as they do now.
>
> Recommendation for which way to go?  #3 is my favorite (but I like to 
> dream...).  But if #2 will work, I'll go with it.  Just desperately 
> trying to prevent having to do #1....
>
> Thanks again for all the help.
>
> Jerry

I found the 'perfect' answer to my problem (I thought) in some comment 
on the web.  It said simply add:

         <cookie-config>
            <path>/</path>
         </cookie-config>

to web.xml.  That did just what I suggested in option 3, and stored only 
one JSESSIONID cookie using path "/".  But (keep reading....).... what 
it didn't tell you is that even though you store only one session id, it 
makes it worse since the same session id is sent to all contexts, both 
the one that created it and all other contexts that did not create it... 
BUT one context can't see the session created by another context.  So 
you are basically sending a different context's sessionid to this 
session, which it doesn't recognize.  So it creates a new one and sends 
it back as the 'one and only' session.  Bottom line.... the problem just 
got worse, with just about every request creating a new session.  I 
really would like to know what possible benefit it would be to use the 
above code in a multi-context application. But that is a question for 
another day.... Certainly NOT a solution I can use.

On to option 2.... success.  I have a header file for each webapp that 
is included at the top of all JSPs.  I simply went into that header for 
each context, and added JSESSIONID cookies with the value of the current 
sessionId and the path for each of the 'alias rewrites' that map to that 
webapp.  So there is now a JSESSIONID cookie for /storeFront that is the 
same value as /order, and hence when I call /storeFront from the browser 
it will send the correct sessionId for /order which will make the /order 
context webapp happy.

I will need to maintain the rewrite-cookie list in my jsp header files 
to make sure there is an entry to match all rewrite aliases defined in 
httpd that map to that context.  But.... it works.

On to the next problem.

Thanks for the help and allowing me to talk this through and get an 
acceptable solution.

Jerry


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Session Persistence Problems -- Epilog

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Jerry,

On 4/11/19 19:34, Jerry Malcolm wrote:
> 
> On 4/11/2019 5:05 PM, Jerry Malcolm wrote:
>> On 4/11/2019 4:22 PM, Christopher Schultz wrote:
>>> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
>>> 
>>> Jerry,
>>> 
>>> On 4/11/19 15:29, Jerry Malcolm wrote:
>>>> Alternatively, if I had a better understanding of how
>>>> sessions are managed by both TC and the browser, it might
>>>> help me figure out what is going wrong.  I know a session key
>>>> is generated by TC and sent back in a response.  And I'm
>>>> assuming that the browser must return that session key on
>>>> subsequent calls.  But if there are several webapps on
>>>> domain, how does the browser differentiate which session key
>>>> to send back on a subsequent response?  Is it just understood
>>>> that the first 'folder' level under the domain (i.e. context
>>>> name) is always a different session key? (myDomain.com/order
>>>> vs. myDomain/account)?   Or does the browser send all session
>>>> keys back per domain and let TC figure out which one, if any,
>>>> to use?   Again, just looking for a little education 
>>>> here....
>>> Do you know if HTTP cookies or URL-parameters are being used
>>> for session-management? If you aren't sure, try logging-in to
>>> your application and look at the URLs and cookies.
>>> 
>>> Typically, a web application will use cookies with the name 
>>> JSESSIONID. If the session identifier is tracked in the URL,
>>> then you'll see ";jsessionid=[id]" in your URLs after the path
>>> but before the query string.
>>> 
>>> It's very easy to "lose" a URL-tracked session id because every
>>> single URL generated by your application must include that
>>> parameter. A sinle miss can cause the session to be lost by the
>>> client. If you are using SSO (always with a cookie), it can
>>> mask the dropping of the session in this way.
>>> 
>>> It's harder to "lose" a session cookie since the browser
>>> typically manages that. Cookies are tracked per web-application
>>> using each application's path. The browser should only return a
>>> single cookie for a given path. If you have applications that
>>> share a URL space (e.g. /master and /master/sub and
>>> /master/sub2) then things can get very confusing for the
>>> browser and the server. It's best not to overlap URL-spaces in
>>> this way.
>>> 
>>> Are you using clustering or anything else like that which might
>>> also cause session-ids to change?
>>> 
>>> - -chris
>> 
>> Thank you so much for the info... I think we're getting
>> somewhere.... I am definitely using cookies and not url parms for
>> the session id. (no clustering).  I went into the firefox
>> debugger and located the cookie storage for the site.  I found a
>> cookie for each webapp context that I am using.  That makes
>> sense.   I think I know what is happening.  Correct my
>> assumptions here:
>> 
>> I have a webapp with context /order.  There is a JSESSIONID
>> cookie for /order as expected. I assume that every time I send a
>> URL from the browser with the /order context, the browser will
>> correctly send the /order session cookie.  So far, so good...
>> 
>> But.... I have a rewrite rule "/storefront" that maps to one of
>> the /order urls.  I assume the browser knows nothing about
>> rewrites, so the browser is going to assume that "/storefront" is
>> simply a different webapp context that it doesn't have a session
>> id cookie for, and therefore doesn't send anything.  Therefore,
>> when the rewritten url becomes another /order url, TC gets an
>> /order request but with no session id, and therefore creates a
>> new session and sends it back for the browser to store (replace)
>> as the /order session id.
>> 
>> So assuming I have analyzed this correctly, that can explain
>> precisely what I'm seeing.   Understanding the problem is a big
>> step... But now I have to figure out how to get around it and
>> make it do what I want. At this point, I see three options:
>> 
>> 1) remove all rewrites from httpd.  That is going to be massive,
>> very difficult, and non-trivial.  And I'll also have to come up
>> with way to handle multi-client variations, etc. that I have been
>> mapping by simply using different rewrites on each site.  This
>> one is not even close to my first choice....
>> 
>> 2) Could I perhaps send my own additional JSESSIONID cookies with
>> the current "/order" session id for the rewrite 'fake contexts'
>> such as "/storefront" so that the browser will basically send a
>> copy of the /order session id with the /storefront url?
>> 
>> 3) I really don't care to have separate sessions for each webapp 
>> context anyway.  In fact, I'd prefer it if there was one session
>> / sessionId for the enter application (all 10 contexts).  Is
>> there any way to send the session id cookie keyed as simply "/"
>> instead of "/<context>"?  All URLs to the domain whether rewrite
>> aliases or actually urls would match this one JSESSIONID cookie
>> and therefore would always send the JSESSIONID.  If that would
>> work, that would solve everything and all rewrites would still
>> work as they do now.
>> 
>> Recommendation for which way to go?  #3 is my favorite (but I
>> like to dream...).  But if #2 will work, I'll go with it.  Just
>> desperately trying to prevent having to do #1....
>> 
>> Thanks again for all the help.
>> 
>> Jerry
> 
> I found the 'perfect' answer to my problem (I thought) in some
> comment on the web.  It said simply add:
> 
> <cookie-config> <path>/</path> </cookie-config>
> 
> to web.xml.  That did just what I suggested in option 3, and stored
> only one JSESSIONID cookie using path "/".  But (keep
> reading....).... what it didn't tell you is that even though you
> store only one session id, it makes it worse since the same session
> id is sent to all contexts, both the one that created it and all
> other contexts that did not create it... BUT one context can't see
> the session created by another context.  So you are basically
> sending a different context's sessionid to this session, which it
> doesn't recognize.  So it creates a new one and sends it back as
> the 'one and only' session.  Bottom line.... the problem just got
> worse, with just about every request creating a new session.  I 
> really would like to know what possible benefit it would be to use
> the above code in a multi-context application. But that is a
> question for another day.... Certainly NOT a solution I can use.
> 
> On to option 2.... success.  I have a header file for each webapp
> that is included at the top of all JSPs.  I simply went into that
> header for each context, and added JSESSIONID cookies with the
> value of the current sessionId and the path for each of the 'alias
> rewrites' that map to that webapp.  So there is now a JSESSIONID
> cookie for /storeFront that is the same value as /order, and hence
> when I call /storeFront from the browser it will send the correct
> sessionId for /order which will make the /order context webapp
> happy.
> 
> I will need to maintain the rewrite-cookie list in my jsp header
> files to make sure there is an entry to match all rewrite aliases
> defined in httpd that map to that context.  But.... it works.

At first, I was actually surprised to see that the browser allowed you
to save a cookie for a "different application root path" but then I
remembered that the browser has no idea what a "context" is and you
can set any path you'd like. You can't set a cookie on /another
domain/ but you can pick another path on your same domain.

So if you have a strict "aliasing" of top-level paths, then this
solution will probably work long-term.

- -chris
-----BEGIN PGP SIGNATURE-----
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAlyw6S0ACgkQHPApP6U8
pFhOHA/9H7Xc/+wCNnBidDZIhlXwUDxya2+wdcLGADJWeafX+O5/DNiSuUmb2i0k
9TKu6e7HJeJQjNSYECRF1dKAmSmR1Ceiq/2SYO/1pHrBXa9HZH2VTp7vzvCXLIKG
l5LXH/nAFPQ8sSRMZcTiUMBC7OtGpcG40VIQ9sKlhB3CmFsUauIjWOM8aHXDXHVB
1XpWCFNT1kCwsrfla6dwJymK+mcW+Tz9oqOT/uCeYvl7HstCD4PsErtvDAmdNgyo
Gnnet5Af3+kqoeVKOJa/MhwtFhLRrQZK1Ru3wth87JRdxlMhmE4kPceYWQW/20Z6
oJ/fzcolplsNwGByqLua2GWadKG0Za5+ENpW6OhkQpnSF/CoZp9JafiTEE6x+wYF
wJAfB4Gnm4XaiAGYn8tjx0w7qLvtGbIQB3gDmULLMNyxdwXZwiM8ddrlPEAjgOvp
cUYc3q+sdASVfktXNrJ0MSLLDFeMRh+673Sam8XiszUHtdCH+WOUFRTrW6Q6EZii
J6rx/GBsMiL7fk1Bv4rWPn6JgyDIws8VjxYfawAUj3iSN8qPLXrfLcMdeDR3rf64
zUMIldYSXyBOKXzO+q2NTy2+aegguFNIWgk60IWPUcSDm2jdTylCmI+NbV35HT+e
A1bNa7qPEyDO2OcvxnXY2W7Oq799xmXSMYfylbwwoVBWIO3Ppj0=
=bzhS
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org