Posted in Flex, ColdFusion | Posted on 11-24-2006 | 5,562 views
If you don't know what I'm talking about, check this post. Essentially - I'm trying to wrap my brain around how to best get Flex 2 talking to ColdFusion in a secure manner. My earlier posts showed how to graphically start up with a login screen, require you to login, and then switch to the main view.
Today I've actually hooked up my Flex code to a real CFC. Let's look at how I did that. The first new lines to my Flex code are:
2
3 <mx:method name="authenticate" fault="alertMsg(event.fault.toString())" result="checkAuthResult(event)" />
4
5</mx:RemoteObject>
This creates an object named "core" that represents my ColdFusion Component. Notice the "source" attribute is the "dot" path, from web root, to the CFC. (More on that later.) I have only one method defined, authenticate, and I've set up both a fault handler and a result handler.
The fault handler simply dumps the error, so lets look at checkAuthResult:
2 var result = event.result;
3 if(result == 'false') {
4 Alert.show("Authentication failed", "Errors", mx.controls.Alert.OK);
5 } else {
6 mainView.selectedChild = mainStage;
7 }
8}
My CFC, which I'll show in a second, will return either true or false. I check the contents of this variable, and depending on the result, either show an error or hide the login stage.
Prety simple, right? The CFC doesn't do much yet. It's authenticate method simply has this:
2 <cfreturn true>
3<cfelse>
4 <cfreturn false>
5</cfif>
Since this is only a demo I'm not going to worry about hooking it up to a database.
So - let me review what I've done: I've defined a CFC service in my Flex code named core. (Not a very descriptive name, but...) I defined a method on this CFC and what Flex should do on error and on the result. I then check the result and either tell the user he didn't login correctly or go ahead and show the main application.
My questions/problems are:
- It seems like the source attribute must be hard coded. This has always been a pain in the butt for me (well, "always" for the few Flex 2 applications I've built) as it means I have to change it from source to production. Obviously I could have set up things differently, but I wish I could abstract that value out - perhaps into Flash Vars. Is that possible?
- I'm not storing the username and password. As I have no idea (yet!) how I'm going to talk securely to the CFC backend, I don't know if I need to. I assume I will - but for now I don't both storing the values.
- As I mentioned, the fault handler should be more intelligent. Any application based on back end services like this should have some nice error handling.
If you want to view this demo, please go here:
http://ray.camdenfamily.com/demos/flexsec3/SimpleRemotingTest.html
As before - please feel free to point anything I did wrong.


As for storing the returned state of the user, you could do one of several things. The most simple would be to have a property on your application that holds the value. The first change I would change there however is updating that from a simple value to some kind of user object so I can add methods like isAuthenticated() or getAccessLevel(). Your authentication call could actually return a cfc which contains the appropriate values to initialize this local as object. Once the application starts to grow, I recommend using something like a ModelLocator to store those values that are needed across and entire application.
<mx:Button id="loginButton" label="Login"
enabled="{(username.text.length == 0 || password.text.length == 0) ? false : true}"
toolTip="{loginButton.enabled == true ? 'Click to submit' : 'Enter username and password'}" click="checkForm()" />
todd: That button looks insane cool! :) I'm not sure I want to use that - but I like it. I'll play with it.
I hesitate in using Flash vars (simply because I'm naive to them). I'm also interested to see what others come up with.
A security question I have is how to ensure that only my Flex application can call the CFC methods. Since I have to set access="remote", the CFC method can be called via the URL.
Regarding my question above, I think I've figured out a way to create a login and logout process and secure the CFC methods so that only my Flex application can call them.
See: http://www.brucephillips.name/flex/secureCFCTest/b...
(you can right click to view the source). The correct username is admin and the correct password is dharma.
I've modified the code Ray had in his latest example and have also incorporated some code I found in the Using ColdFusion MX With Flex 2 Adobe PDF documentation. There is a section in that document that discusses Flash Remoting Update and Authentication.
Basically, I have the Flex application set the remote credentials to the username and password entered by the user (see http://livedocs.macromedia.com/flex/2/langref/mx/r...) and its discussion on method setRemoteCredentials. The login method in my CFC uses CFLogin to process the user's provided information that is now in the CFLogin scope. If the correct information is provide the roles attribute for cfloginuser is set to flexadmin.
My getData CFC function uses the roles attribute set to flexadmin. Thus, unless the user has successfully logged in he cannot call this method from flex (or anywhere else such as in the URL).
I also provide a logout capability on the "secure" view in the Flex app, which will call a logout function in the CFC.
Let me know what you think about this variation.
Bruce
Thanks for the tip about using access="public" instead of access="remote". I did not know you could do that, but tested the demo I mention above and access="public" worked fine.
I still like the idea of using setRemoteCredentials in the RemoteObject call to a CFC function that uses CFLogin. You can then user role based security.
IIRC, use of setCredentials() requires cflogin, something I'm no fan of.
There are also settings in there to return structure keys as all lowercase instead of uppercase and a few other things.
I am in the same dilemma about moving from development to production. I was going to look next on how to do remote object calls using actionscript only instead of the mxml tags, to see if I can construct the object on the fly instead of hardcoding.
[Add Comment] [Subscribe to Comments]