Handling sessions across subdomains

748 views
Skip to first unread message

daamsie

unread,
Dec 6, 2010, 1:04:22 AM12/6/10
to cfaussie
Having some major battles trying to get sessions to work neatly across
subdomains at the moment. We're using J2EE session management. I
implemented the advice in this blog post to ensure that a domain
cookie was set, rather than the default which is a cookie specific to
the subdomain; http://www.coldfusionmuse.com/index.cfm/2006/7/28/sessions.and.subdomains

Then I noticed that a jsessionID cookie was still being set for the
subdomain and it was different to my domain cookie which had been set
on our main site, not the blog. So my next idea was to override the
subdomain cookie. Here's the code I ended up with:

=========
<cfapplication name="foo" sessionmanagement="yes"
sessiontimeout="#CreateTimeSpan(0,1,30,0)#"
applicationtimeout="#CreateTimeSpan(0,1,30,0)#" setclientcookies="no" /
>

<!--- handling session cookies ourselves --->
<cflock scope="Session" type="exclusive" timeout="30">
<cfif isDefined('cookie.jsessionID')>
<cfset session.sessionID=cookie.jsessionID />
<cfelse>
<cfcookie name="jsessionid" domain=".foo.com"
value="#session.sessionid#">
</cfif>
<cfcookie name="jsessionid" value="#session.sessionid#"><!--- set
explicitly for the subdomain since there doesn't be any way to stop cf
from setting this itself --->
</cflock>
=========

So now, I managed to get two cookies set with identical sessionIDs.
Woopee! Well, not quite.

Some of our blogs are private, so whoever visits it will need to enter
a password to get in. And the whole thing fails miserably there.
People try to log in, it logs them in successfully and then redirects
them to the blog and then they're not logged in any more.

To analyze the problem I cfmailed myself the session scope before
attempting to login, after the successful login and again after the
redirect. Here's what it looks like (simplified for clarity's sake)

======
Before Login:
-----------------
session.userid 1
session.sessionid ffffff
session.urltoken CFID=1&CFTOKEN=5&jsessionid=44444


======
After Successful Login (the login is successful here, because the
session.secure_blogIDs variable now exists)
------------------
session.userid 1
session.secure_blogIDs 1
session.sessionid ffffff
session.urltoken CFID=1&CFTOKEN=5&jsessionid=44455

======
After Redirect (note, secure_blogIDs variable disappears)
------------------
session.userid 1
session.sessionid ffffff
session.urltoken CFID=1&CFTOKEN=5&jsessionid=44466


As you can see, the session.urltoken keeps changing, though the
session.sessionID manages to stay the same. I've tried manually
setting the session.urltoken to ensure it is consistent as well.
Managed to do that, but the same problem still happens.

Does anyone have a better understanding of how these j2ee sessions
work? I'm just not having much luck with them and not finding any
useful information on the interwebs about it either.

Cheers,
Peter

daamsie

unread,
Dec 6, 2010, 1:45:45 AM12/6/10
to cfaussie
I should add, we're using CF9 Enterprise. Though I don't think that
plays a part in this problem.

MrBuzzy

unread,
Dec 6, 2010, 1:51:23 AM12/6/10
to cfau...@googlegroups.com
Hi Peter, I use j2ee sessions and use cookies across sub domains with no issue :)

Without delving too deeply, I'd suggest removing your 'custom' session cookie handling and clear your cookies from your browser before continuing.

Keep this in mind, you will only have one jsessionid, but you may still have multiple coldfusion sessions aka scopes, this is defined by the cfapplication tag. Do your blogs each have their own application name, and therefor session scopes? That may be why people appear to be logged out, because you are bouncing between different session scopes. If you want to store the login state across multiple subdomains they must all share the same application name.

Btw, I'd strongly advise using an Application.cfc instead. It just makes the whole thing easier to manage (and debug perhaps).

Looking at the code you've provided I'm guessing you are not using cflogin, but rolling your own login mechanism, by storing the login state in session. Nothing wrong with that :)

A couple of other tips;
Use the onsessionstart method to log when a session really starts.
If you're invalidating the jsessionid cookie a new session will be created for each application. Probably not what you want :)
If you are passing the jsessionid across multiple coldfusion instances, you will need to setup session replication.

Sorry I have to run but I'll keep an eye out if you have follow up questions.

Cheers.

Sent from my iPhone

> --
> You received this message because you are subscribed to the Google Groups "cfaussie" group.
> To post to this group, send email to cfau...@googlegroups.com.
> To unsubscribe from this group, send email to cfaussie+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/cfaussie?hl=en.
>

daamsie

unread,
Dec 6, 2010, 5:38:20 AM12/6/10
to cfaussie
Thanks for the answer :) Maybe running the site and the blogs on
separate instances is the main problem here. I don't have any session
replication set up. That said, I did have the blogs recognizing the
session from the main site. As in, it would pick up on the username,
userid, etc.. that were all set prior to hitting up the blog. So was
able to carry across. It's just when some members try to log in to
these private blogs, it lost it. Seems quite crazy to me. For now,
I've reverted the code back to what it was before - which basically
does no manual setting of cookies and enables clientManagement again.
The login to private blogs works as a result, but the carrying across
of sessions from the main site doesn't.

My only question with your approach is how do you ensure the
jsessionid cookie is set as a domain cookie? By default it always
includes the subdomain and I can't find any way of overriding that. If
setDomainCookies would work on jsessionIDs, then I guess the problem
would be solved, but it doesn't :(

And yeah, you're right, I probably should switch these blogs to
application.cfc. We're using that on the main site now, but haven't
done so for the blogs yet. Now's probably as good a time as any.

On Dec 6, 5:51 pm, MrBuzzy <mrbu...@gmail.com> wrote:
> Hi Peter, I use j2ee sessions and use cookies across sub domains with no issue :)
>
> Without delving too deeply, I'd suggest removing your 'custom' session cookie handling and clear your cookies from your browser before continuing.
>
> Keep this in mind, you will only have one jsessionid, but you may still have multiple coldfusion sessions aka scopes, this is defined by the cfapplication tag. Do your blogs each have their own application name, and therefor session scopes? That may be why people appear to be logged out, because you are bouncing between different session scopes. If you want to store the login state across multiple subdomains they must all share the same application name.
>
> Btw, I'd strongly advise using an Application.cfc instead. It just makes the whole thing easier to manage (and debug perhaps).
>
> Looking at the code you've provided I'm guessing you are not using cflogin, but rolling your own login mechanism, by storing the login state in session. Nothing wrong with that :)
>
> A couple of other tips;
> Use the onsessionstart method to log when a session really starts.
> If you're invalidating the jsessionid cookie a new session will be created for each application. Probably not what you want :)
> If you are passing the jsessionid across multiple coldfusion instances, you will need to setup session replication.
>
> Sorry I have to run but I'll keep an eye out if you have follow up questions.
>
> Cheers.
>
> Sent from my iPhone
>
> On 06/12/2010, at 5:04 PM, daamsie <pe...@travellerspoint.com> wrote:
>
>
>
>
>
>
>
> > Having some major battles trying to get sessions to work neatly across
> > subdomains at the moment. We're using J2EE session management. I
> > implemented the advice in this blog post to ensure that a domain
> > cookie was set, rather than the default which is a cookie specific to
> > the subdomain;http://www.coldfusionmuse.com/index.cfm/2006/7/28/sessions.and.subdom...

MrBuzzy

unread,
Dec 6, 2010, 6:25:01 AM12/6/10
to cfau...@googlegroups.com
I'll do some digging around tomorrow and get back to you.

You've now got me wondering if my jsessionid's are domain cookies or not...

Sent from my iPhone

MrBuzzy

unread,
Dec 6, 2010, 9:02:07 PM12/6/10
to cfau...@googlegroups.com
Hi Peter,

I did a bit more investigationing :)

To recap, your problem is twofold;
1. You'll need session replication between CF instances
2. You need to force the jsessionid to be a domain cookie

Session replication can be annoying. But not impossible. You might need to consider running your login page in the same CF instance as the blogs (sub domains). Or re architect it so the login state is stored in the cookie scope instead of session. Or consider a single sign on mechanism. Or use Railo ;)

The jsessionid is an artifact of JRun (J2EE really), intercepting or rewriting it using CF will also be a bit hacky and problematic. 
Instead you can force JRun to set a domain cookie, as follows;

Edit jrun-web.xml and add the cookie-config element. Here's an example;

<session-config>   

<persistence-config>

<active>false</active>

</persistence-config>

<cookie-config>

<active>true</active>

<cookie-max-age>-1</cookie-max-age>

<cookie-secure>true</cookie-secure>

<cookie-domain>.foo.com</cookie-domain>

<cookie-comment></cookie-comment>

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

<cookie-name>jsessionid</cookie-name>

</cookie-config>

</session-config>


This may not be suitable if you are hosting more that one primary domain on that CF instance.

For more info see;
http://livedocs.adobe.com/jrun/4/Programmers_Guide/techniques_servlet13.htm

Hope this helps, it'd be nice to hear if anyone else on the list has ideas.

Cheers.

Sent from my iPhone

On 06/12/2010, at 9:38 PM, daamsie <pe...@travellerspoint.com> wrote:

charlie arehart

unread,
Dec 6, 2010, 9:44:54 PM12/6/10
to cfau...@googlegroups.com

I don’t know if I’d call the jsessionid a “remnant” so much as a feature, and yes, of J2EE more than JRun itself. :-) As far as I can recall, one would have the same on Tomcat, WebLogic, etc. as (again, I think) it’s the J2EE spec way of doing session id cookies. (As most here may already know, CF uses that if one enables “j2ee sessions” in the CF Admin, to cause use of JRun’s underlying session mgt vs CF’s.)

In mentioning Railo, MrB, I’m curious if there’s something particular that you’re thinking of that differs. Or was this just more of a “maybe it’s different on Railo” kind of suggestion :-)

Great stuff on the jrun-web.xml config. I recall seeing that in the past but had forgotten about it myself.

 

/charlie

 

From: cfau...@googlegroups.com [mailto:cfau...@googlegroups.com] On Behalf Of MrBuzzy
Sent: Monday, December 06, 2010 9:02 PM
To: cfau...@googlegroups.com
Subject: Re: [cfaussie] Re: Handling sessions across subdomains

 

Hi Peter,

I did a bit more investigationing :)

To recap, your problem is twofold;
1. You'll need session replication between CF instances
2. You need to force the jsessionid to be a domain cookie

Session replication can be annoying. But not impossible. You might need to consider running your login page in the same CF instance as the blogs (sub domains). Or re architect it so the login state is stored in the cookie scope instead of session. Or consider a single sign on mechanism. Or use Railo ;)

The jsessionid is an artifact of JRun (J2EE really), intercepting or rewriting it using CF will also be a bit hacky and problematic. 

Instead you can force JRun to set a domain cookie, as follows;


<snip>

MrBuzzy

unread,
Dec 6, 2010, 10:21:40 PM12/6/10
to cfau...@googlegroups.com
I didn't say remnant I said artifact, maybe they mean the same thing :) 
Agreed it's an artifact of the J2EE spec and server (in this case JRun). 

Re: Railo, it has some cool mechanisms to store session data centrally or distributed for example you can use EHCache. I'm just recalling some of the presentations at cfoanz. I've never done it but it make sense and seems like an alternative to using 'replication' between CF instances which seems to use multicasting and rmi etc and is dependant on JRun or Tomcat or whatever.

Sent from my iPhone
--

charlie arehart

unread,
Dec 6, 2010, 11:03:42 PM12/6/10
to cfau...@googlegroups.com

Yep, sorry. They do mean about the same thing in my mind, but I should have been more accurate in my quote. :-)

As for storing sessions in other than memory, I’ll note as well that that is again something that the J2EE servers all offer. Even JRun has it, but it’s not exposed by CF. One could find the underlying xml entries to tell it also to store session data to files, for instance. Some J2EE servers also support storing them in a database. I think it may be precluded in the Server deployment but should be fully supported in the Multiserver deployment, since that’s pure JRun.

Anyway, not disagreeing that Railo may have something else that CF doesn’t (and to be clear, CF doesn’t expose alternative session storage in the interface). Was just curious what you were thinking of. Thanks.

/charlie

 

From: cfau...@googlegroups.com [mailto:cfau...@googlegroups.com] On Behalf Of MrBuzzy
Sent: Monday, December 06, 2010 10:22 PM
To: cfau...@googlegroups.com
Subject: Re: [cfaussie] Re: Handling sessions across subdomains

 

I didn't say remnant I said artifact, maybe they mean the same thing :) 

daamsie

unread,
Dec 6, 2010, 11:56:14 PM12/6/10
to cfaussie
Excellent stuff. Going to give this a whirl now.

I updated to an Application.cfc on the blogs today. A bit messy at
first, but that's running smoothly now.

If I can't replicate sessions, I may just have to stick the blogs back
under the same instance. The main reason for separating them was to
spread the load somewhat and have it so one instance could still be
running if something went wrong with the other one. It's not a major
deal though and I'd rather have logins working across these
subdomains.

Thanks for looking into it in such detail. Much appreciated ;) !


On Dec 7, 3:03 pm, "charlie arehart" <charlie_li...@carehart.org>
wrote:

daamsie

unread,
Dec 7, 2010, 5:59:05 PM12/7/10
to cfaussie
Alright, I added the jrun-web.xml settings for both the blogs and www
instances.

There's an important change that needs to be made to those settings
you had - JSESSIONID seems to have to be uppercase. That cookie just
resets on every page otherwise.

Sessions seem to be working smoothly now, across subdomains and
instances. Thanks a heap for your help. It was just the solution I
needed!

Peter

daamsie

unread,
Dec 7, 2010, 6:02:02 PM12/7/10
to cfaussie
A follow up on that uppercase thing - this article is what pointed me
to it:

http://www.codeproject.com/KB/architecture/ColdFusion.aspx?msg=3412894

quote: "J2EE, however, requires that JSESSIONID be included as
uppercase."
Reply all
Reply to author
Forward
0 new messages