This post is not ColdFusion specific, but this came about while using ColdFusion 10 with the Tomcat servlet container that comes with it.
Ray was asking today about making Domain cookies with Tomcat and CF10 while using JEE Session Tokens (JSESSIONID). When using ColdFusion Session Tokens (CFID/CFToken) this is a trivial matter, because we have complete control over the cookies which are set.
The Above example is from Shilpi's post on Security Improvements in CF10. We can use this.sessioncookie.domain to specify the exact domain for which we want the cookies set.
Not as easy with JEE TokensWhen we use JEE Session Tokens, however, things are a bit trickier, because it is not actually ColdFusion setting the cookies, it is the servlet container that is doing it. In this case, that servlet container is Tomcat 6.
By default Tomcat seems to set non-domain cookies. They do not contain the leading dot (.) to make it so that the browser submits the cookie to all subdomains/hosts of the specified domain.
What is a domain cookie?If the domain value of my cookie is 12robots.com then that cookie will ONLY be submitted if I visit a page at http://12robots.com. The cookie will NOT be submitted if I try to visit a page at admin.12robots.com, test.12robots.com, or even www.12robots.com.
However, if the cookies domain attribute is set to .12robots.com then the cookie would be submitted to any of the above mentioned domains and any other host/subdomain of 12robots.com.
Obviously, this is very useful. So how can I make this work if I chose to use JEE Session Tokens?
Making it Work
To enable this in Tomcat, we need to dig into some configurations and make some changes. The file we will be look at is server.xml. On a standard CF install, this file can be found at <cf_home>/cfusion/runtime/conf/server.xml and the part we are concerned with looks like this.
The default host is localhost. This is specified in the <Engine> directive. Within the Engine directive we can set up virtual hosts. This is a virtual host for the localhost domain. If you want to, you can keep this one and add others, we'll look at this shortly, or you can just modify this one if you are only serving a single domain from this server.
Here is how you would modify server.xml to support serving a different domain (11robots.com is a fake domain I made up for working locally) with a specific domain attribute in the session cookies. (I've stripped out comments to make it easier to look at)
I have added a <Context> directive to the Host and told it specifically where to look for the wwwroot folder (this is also how you would tell Tomcat to look in a different folder for files). I have also specified that the path for this app will be "/" and, the point of this exercise, I have told it to use the domain .11robots.com so that it would not automatically use just 11robots.com or www.11robots.com.
As you can see from the image below, it worked.
Note: The Valve directive is now inside of Context not next to it.
Second Note: I had to change the pattern attribute of Valve to "common". The pattern that was in there before started causing errors for me. The comment said the pattern was the same as if you had used "common", so I used "common".
So what if you need to do this with multiple domains?
If you need to do this with multiple domains, the changes aren't much different. In fact, it is mostly just a matter of adding a second (or third, or more) Host with its own context.
There is extra thing to know and one additional step. You cannot use the appBase="webapps" again. It is already in use for the first domain. So we need to create another. You can name it whatever you like, Tomcat will take care of creating the folder. We then also need to create a webroot for the new host. I placed mine in the cfusion directory right next to wwwroot/, in the example below, I called it iocroot/. I then copied the webfiles I needed to in there.
Note: One, and only one, of your virtual host's names MUST match the defaultdomain specified in <Engine>
So in the example above, I am now able to serve applications from 11robots.com and localhost.ioc while specifying the exact cookie domain value for each when using JEE Session Token.
Final Note: It is possible there is a better way to do this. If anyone knows of one, I would love to hear about it. I have not used CF10 much, nor am I a Tomcat expert, so I am willing to learn if someone cares to teach. :)