The Solution to Flex Remoting Over SSL
If you've tried calling ColdFusion CFCs with RemoteObject over SSL in your Flex apps, you probably feel my pain already, because you have either tried to get it working and gave up, or had a heck of a time getting it working. Adobe's documentation for this specific need wasn't helpful to me, and discussion about it online is relatively sparse and unsure as well, from what I've seen. My intranet environment at work demanded that I get remote communication with CFCs working over SSL, so as I neared completion of my first couple Flex apps, I needed to get an understanding of this issue. Hopefully it will be useful to others.
So, what's the problem? In a nutshell, when you try to use the RemoteObject component in a Flex app to communicate with CFCs, the default installation of ColdFusion 8 and Flex Builder 3 will compile your app to communicate with the ColdFusion server over HTTP (http://yourserver.com/flex2gateway/), not over HTTPS (https://yourserver.com/flex2gateway/cfamfsecure), regardless of whether the SWF was loaded over HTTPS or not.
If your site exists in both HTTP and HTTPS, you may not even be aware this is happening. I wasn't aware of it while I was developing on my local machine. But our production server hosts its site only in HTTPS and the site on port 80 is a nearly empty site that redirects all requests to the SSL-protected version of the site. So this behavior broke my Flex app.
If your site exists only in SSL or sensitive data is being transmitted to and from the Flex app and the CFCs, you probably are trying to get RemoteObject to communicate over SSL.
Quick workarounds. If you have time and leniency to skirt the issue, you can avoid the RemoteObject/SSL issue. You can always use the HTTPService and WebService components instead of RemoteObject. But like most workarounds, this has its disadvantages and limits you from the benefit of using RemoteObject.
I imagine you also could set up a ColdFusion mapping to make the CFCs available on the HTTP site, but this solution is viable only if you really don't care about security, in which case you probably wouldn't have your site wrapped in SSL anyway.
The solution. What makes the solution tricky is that there are a few things that have to be configured properly, and there are some pitfalls along the way that can be misleading. The primary solution lies in some changes to the ColdFusion server's config files services-config.xml and remoting-config.xml. These both reside in {ColdFusion installation}\wwwroot\WEB-INF\flex\. For instance, on my Windows workstation, this is located at c:\ColdFusion8\wwwroot\WEB-INF\flex\.
1. Add the secure channel to remoting-config.xml. ColdFusion 8 already has a channel in its configuration for RemoteObject over SSL--it is called "my-cfamf-secure"--it just isn't configured to be used. So you have to add the "my-cfamf-secure" channel to remoting-config.xml. To do this, add <channel ref="my-cfamf-secure" /> to the <default-channels> node and the <channels> node for the "ColdFusion" destination.
In other words, your new remoting-config.xml file should look like this:
-
<?xml version="1.0" encoding="UTF-8"?>
-
<service id="remoting-service" class="flex.messaging.services.RemotingService" messageTypes="flex.messaging.messages.RemotingMessage">
-
<adapters>
-
<adapter-definition id="cf-object" class="coldfusion.flash.messaging.ColdFusionAdapter" default="true"/>
-
<adapter-definition id="java-object" class="flex.messaging.services.remoting.adapters.JavaAdapter"/>
-
</adapters>
-
<default-channels>
-
<channel ref="my-cfamf-secure"/>
-
<channel ref="my-cfamf"/>
-
</default-channels>
-
<destination id="ColdFusion">
-
<channels>
-
<channel ref="my-cfamf-secure"/>
-
<channel ref="my-cfamf"/>
-
</channels>
-
<properties>
-
<source>*</source>
-
<!-- define the resolution rules and access level of the cfc being invoked -->
-
<access>
-
<!-- Use the ColdFusion mappings to find CFCs, by default only CFC files under your webroot can be found. -->
-
<use-mappings>false</use-mappings>
-
<!-- allow "public and remote" or just "remote" methods to be invoked -->
-
<method-access-level>remote</method-access-level>
-
</access>
-
<property-case>
-
<!-- cfc property names -->
-
<force-cfc-lowercase>false</force-cfc-lowercase>
-
<!-- Query column names -->
-
<force-query-lowercase>false</force-query-lowercase>
-
<!-- struct keys -->
-
<force-struct-lowercase>false</force-struct-lowercase>
-
</property-case>
-
</properties>
-
</destination>
-
</service>
This brings me to the first pitfall to watch out for. Be sure to list <channel ref="my-cfamf-secure" /> ahead of <channel ref="my-cfamf" /> so that ColdFusion will try the secure channel first.
2. Add a property to make IE happy. At this point, your configuration will be adequate for Firefox. However, IE still seems to get tripped up and tries to access the insecure channel. To fix this, just add <add-no-cache-headers>false</add-no-cache-headers> to the <properties> node of the <channel-definition> nodes for "my-cfamf" and "my-cfamf-secure" in services-config.xml.
I won't display the entire services-config.xml file here, but your "my-cfamf" channel definition will now look like this:
-
<channel-definition id="my-cfamf" class="mx.messaging.channels.AMFChannel">
-
<endpoint uri="http://{server.name}:{server.port}{context.root}/flex2gateway/" class="flex.messaging.endpoints.AMFEndpoint"/>
-
<properties>
-
<polling-enabled>false</polling-enabled>
-
<serialization>
-
<instantiate-types>false</instantiate-types>
-
</serialization>
-
<add-no-cache-headers>false</add-no-cache-headers>
-
</properties>
-
</channel-definition>
And the "my-cfamf-secure" channel definition:
-
<channel-definition id="my-cfamf-secure" class="mx.messaging.channels.SecureAMFChannel">
-
<endpoint uri="https://{server.name}:{server.port}{context.root}/flex2gateway/cfamfsecure" class="flex.messaging.endpoints.SecureAMFEndpoint"/>
-
<properties>
-
<polling-enabled>false</polling-enabled>
-
<serialization>
-
<instantiate-types>false</instantiate-types>
-
</serialization>
-
<add-no-cache-headers>false</add-no-cache-headers>
-
</properties>
-
</channel-definition>
Some more pitfalls to consider. These can be really misleading, making you think your changes aren't working.
A. Flex Builder incorporates these settings into your app when it compiles the SWF. Go to your Flex project's properties, under "Flex Compiler", and you'll see a reference to your services-config.xml file. If your SWF is compiled on a workstation that hasn't had these changes, it will not work on your server, even if you did change your server's config files. So be sure that your local installation of ColdFusion has its services-config.xml and remoting-config.xml files updated just like your production server.
B. On a related note, be sure to recompile an app if you've compiled it before making these config changes. You can recompile in Flex Builder by going to Project > Clean. That option will ensure that you have a clean, recompiled SWF.
C. If your SWF file is actually served on port 80, it will not be allowed to communicate over the secure channel unless you tell it that it is permissible to do so by setting up a crossdomain.xml file. Check out Shannon Whitley's post SSL, crossing domains, and Flex to read a bit on that.
Tools for the job. With the right tools, you can test all of these things out on your own. For instance, Firebug and Fiddler are great tools for Firefox and IE respectively that clearly show your Flex app's behavior, and whether it is attempting to access the secure or insecure channel. They also show the app attempting to access a crossdomain.xml file when the SWF file was loading over HTTP, because it's first attempt is to make a cross-domain connection to the secure HTTPS channel.
The great thing about this configuration is that your SWFs will use the secure channel when they can, but silently fail over to the insecure channel. So your development workstation doesn't have to use SSL, but your compiled apps will utilize it when you move them to your production server. This is cleaner than setting up a separate "Destination" in remoting-config.xml, or other solutions that require changes to your app's code. Alas, I am still green in the Flex universe and don't claim anything different. Nevertheless, this solution is working perfectly for me and I hope it proves useful for you.

March 26th, 2008 at 3:53 pm
I have fought issues with RemoteObject config on our prod server until becoming disgusted and finding another way. Your post inspired me to at least try your recommendations and I did so today to no avail. I’m absolutely convinced there’s something screwed up on that box, and I don’t have the necessary permissions to adequately diagnose or repair.
Just wanted to say thanks for posting — I’m sure it will help others.
April 7th, 2008 at 2:02 pm
@hsTed: I am really bummed to hear that. If you want, send me your info/configs and I’d be happy to offer a second opinion.. FWIW..
May 1st, 2008 at 7:34 am
Thanks a lot!
The trick is also working for a BlazeDS/Tomcat backend.
May 2nd, 2008 at 7:39 am
We have an odd thing (actually more than odd down right frustrating) happening in our production environment. In our test environment, we can use both SSL and non SSL remote objects connections without any issues. However, our production environment won’t return objects from remote objects calls over SSL which are greater than 2k or so. Our non-ssl calls in production work just fine, and calls which only return small data are fine. The major difference with our production enviroment ssl setup and our test ssl setup is our production servers our load balanced were the SSL occurs on the load balancer, so the CF8 server/Jrun server actually sees non-ssl calls. The gateway logs show the correct data being sent in a message.
Anyone experienced anything similar in load balanced ssl environments?
May 16th, 2008 at 11:44 am
Thanks! This method works great! Thanks for the the information. I was beginning to pull my hair out with the standard “Send Failed” error message. And I was dreading using one of the other methods which attempts to create a “code based” solution.
June 11th, 2008 at 12:52 pm
[…] did a google search on services-config secure and found this page which was very helpful. This page was also an interesting read. Before reading these, I did not […]
June 13th, 2008 at 9:31 am
One other quick note. I also had to add the endpoint to my remoteobject calls like such:
endpoint=”https://onestoptest.ecu.edu/flex2gateway/cfamfsecure”
June 18th, 2008 at 3:32 pm
“They also show the app attempting to access a crossdomain.xml file when the SWF file was loading over HTTP, because it’s first attempt is to make a cross-domain connection to the secure HTTPS channel. The great thing about this configuration is that your SWFs will use the secure channel when they can, but silently fail over to the insecure channel.”
I found this to be the case with Firefox and Internet Explorer. However on Safari 3.1.1, if the server is using a self-signed certificate, this causes the browser to stall indefinitely at trying to get https://example.com/crossdomain.xml. If the certificate is signed, then no problem and it uses the http connection after getting https://example.com/crossdomain.xml.
June 19th, 2008 at 6:00 am
Josh, Thanks for this blog. I and another developer were just about going crazy for two weeks after the upgrade to CF8. None of the RemoteObject calls would work from Flex, even the ones that had worked with CF7. Then we got AIR applications working with the exact same server and .cfcs that the .swf couldn’t connect to. The browser was IE, and the fix was the add-no-cache-headers setting, like you illustrate above.
Thanks for saving what sanity I have left.
Scott Emery
June 19th, 2008 at 7:47 am
@Zach: For an AIR app, that endpoint should be necessary, but for a Flex app on your website, you should be able to just use destination=”ColdFusion”. Isn’t that right?
@Adam: Your issue seems to be different than what I’m covering here. But no, I have never experienced the kind of problem you’re describing.
@Jamie: Wow, that’s good to know. Even though I am a Safari user on my Mac at home, I didn’t even think to check this for my app at work. That’s why my employer should give me a Mac.
@Scott et al: Like I said in the beginning of the post, we’re all feeling the pain together, anyone who has tried this! I’m so glad to see this post is helping people!!
August 11th, 2008 at 7:28 pm
Do you know if there is similar information around for Coldfusion 7? Is it just a matter of creating a new channel in services-config.xml? as there is no remoting-config.xml in the WEB-INF/flex directory… however the flex.messaging.endpoints.SecureAMFEndpoint class exists.
I can’t find the mx.messaging.channels.SecureAMFChannel class though.
ANyone got flex 3 remote object working with Coldfusion 7?
August 26th, 2008 at 2:34 pm
Thanks for posting this. After 2 days, it dawned on me that the problem might be with connecting to CF (8.0.1) over SSL and viola! Here I am.
I just wanted to mention 2 things:
1. After you make the changes to the XML files, you need to restart the CF server to pick up the changes as well as cleaning and recompiling the project.
2. Using “add-no-cache-headers” didn’t work in Firefox 3.0.1 (I didn’t test MSIE 7). Without it, both FF3 and MSIE 7 work. Is this a problem only for MSIE 6?
September 16th, 2008 at 6:11 pm
Hey !!!
Amazing job, really nice work your solution work amazing.
I am using CF 8.01 Standart and Flex 3.01. Work fine in IE 7 and FireFox 2
Again Thanks
September 24th, 2008 at 5:24 pm
I have done everything listed but still no luck. https and http both work internally on the production server but https does not work ouside the network. Any other possibilities? I am getting in a time crunch. Thanks
September 25th, 2008 at 4:16 pm
@Adrian: My understanding is that the add-no-cache-headers tag is only necessary for IE.
@John Gag: After doing these things, have you rebuilt and recompiled the Flex app, and then deployed that new swf?
September 25th, 2008 at 4:48 pm
@Josh: Yes, I followed the blog very carefully. I am reinstalling ColdFusion and setting up the webserver again to see if that helps. If not I am completely lost! Thanks
September 25th, 2008 at 5:18 pm
@EVERYONE: After reinstalling ColdFusion and resetting the administrator it now works! If someone cannot get it to work try enabling RMI over SSL and configuring the keystore… Thanks so much!!!
September 25th, 2008 at 5:54 pm
That is a very good point about configuring the keystore… If your cert isn’t from a recognized CA, that is a necessary step. Thanks!
September 25th, 2008 at 6:30 pm
A couple weird things that I have noticed after gettting it working in FireFox. The only way I can get it working is if I change the endpoint uri to uri=”https://{server.name}:{server.port}{context.root}/flex2gateway/” instead of uri=”https://{server.name}:{server.port}{context.root}/flex2gateway/cfamfsecure”. The IE fix is not working though so I keep plugging
September 29th, 2008 at 12:40 pm
Thanks for putting this together. I fumbled my way through this right when Flex 3 was released and finally got it working. However, I’m trying again on a new server and I feel like I must have been lucky the first time.
I’ve done as outline above, but now I’m getting this message:
“Destination ‘ColdFusion’ not accessible over channel ‘my-cfamf-secure’.”
Has anyone seen this?
October 5th, 2008 at 5:08 pm
So, I figured out my problem(s).
1. I hadn’t rebooted the server, but then I got the original error.
2. I found that I had double-added the false line. I removed that, and voila! It works.
Lesson: The order and entries in these files are very important, as is rebooting the ColdFusion Service.
Thanks again.
October 14th, 2008 at 9:02 am
I have a flex project that works with coldfusion MX 7. In the debug mode, all works well(i.e I am able to connect to the cfc functions). I have 2 questions. Firstly, on my computer which has CF server installed, I “Export Release Build” my project, and after the build is complete, when I try to run the swf file I get “Send Failed” error and the browser just hangs. The build creates a folder in the same way as the app-debug folder. I don’t understand why I am getting this error.
Secondly, I need to move this to another server which has CF 7 installed. How do I go about doing this?
If anyone can point me to resources on the web or provide me a solution, that would be greatly appreciated.
Thanks a lot.
October 16th, 2008 at 4:24 pm
I still cannot get this thing to work over IE!! Biggest headache of all headaches
October 20th, 2008 at 6:08 pm
I am having trouble getting my Flex 3 Dashboard to work in IE 7 over SSL(it works in Firefox, thanks a million to cranky). I have looked over numerous blogs and followed the instructions in this blog, line by line. If anyone has any advice other than the comments and posts in this blog, it would be greatly appreciated.
November 12th, 2008 at 3:18 am
Is there a way to modify the services-config & flex-config file at runtime .. without recompiling the swf ?
My case is that i need to deploy my applications in different environments.
November 15th, 2008 at 9:12 pm
Nice article, you have helped me out here. THANK YOU!
One thing, How could I set up the *-config files so I could discriminate on HTTP vs HTTPS calls. For instance some remote calls would be secure and others not. My initial thought is to create a new destination (e.g. Coldfusion_secure) but then again I realy shouldn’t be thinking…
November 16th, 2008 at 12:11 pm
The seperate destination worked well for splitting the calls into secure and non-secure, with a caveat. In the remoting-config.xml, if in the tag I put both “my-cfamf-secure” and “my-cfamf” channels it would only use the non-secure channel. Regardless of order. Removing the “my-cfamf” worked. Now I only have to specify “Coldfusion” or “Coldfusion_secure” in my destination of the remote object. Here is the relevant code from my remoting-cofig.xml file.
*
false
remote
false
false
false
*
false
remote
false
false
false
November 16th, 2008 at 12:13 pm
The seperate destination worked well for splitting the calls into secure and non-secure, with a caveat. In the remoting-config.xml, if in the tag I put both “my-cfamf-secure” and “my-cfamf” channels it would only use the non-secure channel. Regardless of order. Removing the “my-cfamf” worked. Now I only have to specify “Coldfusion” or “Coldfusion_secure” in my destination of the remote object.
November 16th, 2008 at 6:11 pm
Excellent information.I used it to solve an issue and really saved my day/night.Thanks.
November 25th, 2008 at 4:53 pm
If you have implemented Adobe TN tn_18516(http://www.adobe.com/go/tn_18516) to allow IIS to handle NTFS security before passing the rquests to CF, you then must apply Adobe TN ebd0cbe3 (http://www.adobe.com/go/ebd0cbe3). This is because the swf and mxml for flash forms are generated in memory to the file check fails. Also, to get AMF remoting to work with the first TN configured, you will also have to create 2 folders in your web root. create flex2gateway and flex2gateway\cfamfsecure. And a HUGE thanks to this blog posting for providing the final answer..(that and Ryan from Adobe)
December 18th, 2008 at 12:54 pm
Thanks dude,
Your blog really helped me to solve one of the problems i am facing with IE over SSL.
Good Job.
January 13th, 2009 at 1:47 pm
Just another thank you! This post helped me solve an issue with a BlazeDS secure polling channel and IE.
March 8th, 2009 at 11:39 pm
This solution is great. When the app is deployed on https - there is no issue, works perfectly as the first one in the default channels is the amf secure channe. When the app is deployed on http, amf requests are first made on https (like you mentioned) and then fails over to http. This also works except that it first tries to CONNECT to the http port (for SSL tunnelling). when the CONNECT request fails then it switches to http. But the CONNECT requests take a long time to fail. Typically 1 minute. Firefox does multiple tries for the CONNECT which takes even longer time. So, for development this will consume more time (just for waiting for the https tunnel to fail and then to switch over to just http). Is this not the behavior that you have - What do you recommend to minimize this wait time. Is there a setting in the browser (or at the OS level) to basically say do not wait for such a long time for ssl connect requests.
March 16th, 2009 at 7:21 pm
Kishore, I am not experiencing this behavior! The SWF fails over immediately. Perhaps something with your local web server is causing this behavior?
April 24th, 2009 at 12:44 pm
“” Be sure to list ahead of so that ColdFusion will try the secure channel first. “”
Hello Josh, I spend a whole day in fixing the problem that my swf files were showing errors on https. I solved the problem by putting secure channel definition over the insecure channel in services-config.xml. I tried to find the reason for this behaviour and came to your blog.
But I still could not find the reason.
April 24th, 2009 at 5:01 pm
Amit, the channels are apparently accessed in the order that they appear in the XML. So by putting the secure channel first, it is accessed first.
The site and port (SSL vs. non-SSL) that a SWF is physically served on by the web server is functionally different than the channel used for the Flex remoting. When you serve up a SWF over SSL, it will still try to communicate over the non-SSL channel. This is, in fact, the very point of this solution.
I hope this clears things up.
April 28th, 2009 at 12:00 am
Hi Josh,
Thanks for the explanation, but why I do not get any error if I run the application on my local server? That is, putting non-secure channel ahead of secure channel in services-config.xml works perfectly fine on both protocols on my local machine.
April 28th, 2009 at 12:29 am
Amit, do you have SSL and non-SSL sites on your local server?
Be sure to use Firebug or Fiddler to see which channel the Flex remoting is using. Like I mentioned in my post, you could be serving the SWF over your SSL site, and yet Flex remoting is transmitting over the non-SSL channel without your knowledge!
If you have the non-SSL channel first, try this. In addition to using Fiddler or Firebug, you can “turn off” your port 80 (non-SSL) site. If Flex remoting is using the non-SSL channel, the request will fail (and hopefully fail over to SSL) when that site is not available.
Does that make sense?
May 5th, 2009 at 4:45 am
Hi Josh, I would like to tell you that we have the split deployment on our production server.
That is, static files like images, js, css and SWF files are places on one server (web server, our build team call it http server) and all other files are on another server (application server). Both are sun servers. Do you think this split deployment could be a problem.
Note: On the webserver there is a configuaration file in which there are entries to route the requests to application server for some particular URLs. For example, *.jpg, *.swf and /messagebroker/* requests are routed to the application server.
May 5th, 2009 at 7:09 pm
Amit, it likely is the cause, although I must admit I have no experience with such a deployment. Have you looked into the server responses with Firebug or Fiddler? You really need to do this to see what is happening.
It may be easier, all circumstances considered, to use a WebService component instead of RemoteObject. This way the SWF served from the one server can call the webservice from the other server. Although I’m certain this isn’t the only or best solution for your scenario.
May 19th, 2009 at 6:12 am
I didn’t have to do anything for a client who had a ssl certificate. The program works the same with either http or https.
I’m confused
May 19th, 2009 at 6:14 am
In my case then how do I forward the http/mydomain to https/mydomain
?
May 19th, 2009 at 9:58 am
is
This brings me to the first pitfall to watch out for. Be sure to list ahead of so that ColdFusion will try the secure channel first.
really important?
June 10th, 2009 at 10:39 am
A good default test also is to address your gateway with a browser.
For example:
http://://flex2gateway/scfamf
http://://flex2gateway/
You should see blank pages for both. If you don’t, your configuration for the one that doesn’t render is off.
I completely agree with the cautions about recompiling with new services-config files that match the server.
If you need to talk only secure-amf, consider removing the insecure channel altogether and see of that works for you.