Shaun Mccran

My digital playground

23
J
U
L
2010

Flex webservices security error accessing url

I've been working with some client side flash developers recently and we came across an unusual error that was being thrown in a Flex application when we were sending a webservice request to a Coldfusion server.

The error was "Security error accessing URL". I thought I'd overcome this a long time ago by using the cross-domain.xml file to allow server access to services.

It appears that there is a security issue with Flash 9 that requires the following line to be added to the CrossDomain.xml file:

view plain print about
1<allow-http-request-headers-from domain="*" headers="SOAPAction"/>

I'm guessing that it is enabling access for SOAP requests to any remote services on that server.

13
O
C
T
2009

ColdFusion structures and case sensitivity examples

Having been using Flex a little more recently I stumbled upon an old issue that I had previously addressed, but it had become second nature, and so I had forgotten about having to learn a workaround in the past. Passing objects from ColdFusion to Flex can be tricky at times, especially as ColdFusion is generally not case sensitive, but Flex is, and this can lead to problems.

I had previously found that how you build your Structure will have an impact the case of the keys. Example one is a Structure built using the traditional dot notation, in a CF 7 and below method:

view plain print about
1<cfscript>
2    newStruct = structNew();
3    newStruct.starter = "Prawn Salad";
4    newStruct.maincourse = "Roast Chicken";
5    newStruct.desert = "Apple Pie";
6
</cfscript>
7
8<cfdump var="#newStruct#" label="Dot notation">

This is the older way of building a Structure, notice how all the keys are uppercase.

The second example is very similar, except that it is using associative array notation, IE brackets to denote the key values, rather than dot notation.

view plain print about
1<cfscript>
2    newStruct = structNew();
3    newStruct["starter"] = "Prawn Salad";
4    newStruct["maincourse"] = "Roast Chicken";
5    newStruct["desert"] = "Apple Pie";
6
</cfscript>
7
8<cfdump var="#newStruct#" label="Struct notation">

Since I originally looked at this ColdFusion 8 (and now 9!) have been released. ColdFusion 8 introduced a new way of creating structures, what casing does this use?

view plain print about
1<cfset newStruct = {
2    starter = "Prawn Salad",
3    maincourse = "Roast Chicken",
4    desert = "Apple Pie"
5} /
>

6
7<cfdump var="#newStruct#" label="CF 8 method">

It also creates an uppercase structure. I haven't really played around with this method enough to see if there is another way of creating a lowercase structure, so for now I'll be sticking to the older associative array method of creating my structures. That way they are easily transferred as a Flex object.

26
A
U
G
2009

Example of inserting a Struct() into a database using keys

A while ago a colleague and I were working on a timesheet application in Flex. The idea was that you could commit a custom timebar object, generated in flex, and it would update the dataset in the back end using the ColdFusion flex gateway.

I came across the code recently, and decided to tidy it up a bit, and make the query dynamic, based on the Struct contents. The obvious limitation to this is that your Struct and your database schema have to match exactly.

I won't go into the Flex application here, but I've emulated its input arguments here with a pre-populated structure.

view plain print about
1<cfscript>
2 timesheetTask = StructNew();
3 StructInsert(timesheetTask, "employeeid", '36');
4 StructInsert(timesheetTask, "timesheetDT", '0');
5 StructInsert(timesheetTask, "projectid", '6');
6 StructInsert(timesheetTask, "weekid", '25');
7 StructInsert(timesheetTask, "taskid", '39');
8 StructInsert(timesheetTask, "hours", '8');
9 StructInsert(timesheetTask, "comment", 'Comments for this task live here');
10 StructInsert(timesheetTask, "szStatus", '1');
11 StructInsert(timesheetTask, "iFirstLineApproval", '23');
12 StructInsert(timesheetTask, "iSecondLineApproval", '34');
13 StructInsert(timesheetTask, "iCurrentApprover", '');
14 StructInsert(timesheetTask, "szRejectReason", '');
15 StructInsert(timesheetTask, "szDescription", '');
16
17 updateTimesheet = createObject("component", "timesheet");
18 updateTimesheet.updateTask(timesheetTask);
19
</cfscript>

Notice that this code also calls the CFC object at the end. The data itself isn't massively important, it's a time object for recording tasks.

Next we have the function, which accepts a Struct() argument called 'taskStruct'. I then loop through the structure, and populate a SQL query using the keys from a collection. The only logic is a check to see if it is the last structure element, as this controls the ',' placement.

view plain print about
1<cffunction name="updateTask" access="remote" returntype="string" hint="Creates a record for timesheet tasks">
2 <cfargument name="taskStruct" type="struct" required="yes">
3 <cfset var count = 0>
4
5 <cfdump var="#arguments.taskStruct#">
6 <cfset variables.structSize = structCount(arguments.taskStruct)>
7
8 <cfquery datasource="#application.dsn#">
9 INSERT INTO [dbo].[timesheet]
10 (<cfloop collection="#arguments.taskStruct#" item="key">
11 [#key#]
12 <cfset count = count + 1>
13 <cfif count LT variables.structSize>,</cfif>
14 </cfloop>)
15
16 <cfset count = 0>
17
18 VALUES(<cfloop collection="#arguments.taskStruct#" item="key">
19 '#arguments.taskStruct[key]#'
20 <cfset count = count + 1>
21 <cfif count LT variables.structSize>,</cfif>
22 </cfloop>)
23 </cfquery>
24
25 <cfreturn true>
26 </cffunction>

That will insert your Struct into a database, in small and tidy manner. It was somewhere around here that we started using cfproperty tags, and creating strongly typed objects for Flex.

03
A
P
R
2009

AIR Phone Book application - Part 3 (Full code)

Below is the full code in one run for the PhoneBook AIR application.

view plain print about
1<?xml version="1.0" encoding="utf-8"?>
2<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="init()"
3    height="280" width="294" horizontalAlign="center" verticalAlign="middle" showFlexChrome="false"
>

4
5<mx:Script>
6    <![CDATA[
7    
8     import mx.controls.Alert;
9 import mx.collections.*;
10 import mx.rpc.events.FaultEvent;
11 import mx.rpc.events.ResultEvent;
12 import mx.collections.ArrayCollection;
13
14     [Bindable]
15     private var loadedData:ArrayCollection;
16
17 public function init():void
18 {
19        // start the move listener
20
        moveListener()
21     // get the remote data
22
    getData()
23 }
24
25 public function moveListener():void
26 {
27        // mover event
28
        outerCanvas.addEventListener( MouseEvent.MOUSE_DOWN, moveWindow );     
29 }
30
31 public function getData():void
32 {
33     popData.getData();
34 }
35
36     public function moveWindow( event:MouseEvent ):void
37     {
38        var str:String = event.target.valueOf();
39
40         // if its a datagrid then don't do the move
41
         if ( str.search("displayPeople") >= 1)
42         {
43             // Do nothing
44
         }
45         else
46         {
47             stage.nativeWindow.startMove();
48         }
49     }
50    
51     public function onMinimize():void
52     {
53         stage.nativeWindow.minimize();
54     }
55    
56     public function onClose():void
57     {
58         stage.nativeWindow.close();
59     }
60
61     public function resultsHandler(event:ResultEvent):void
62     {
63        // trace(event.result)
64
        displayPeople.dataProvider = popData.getData.lastResult
65     }
66
67     public function faultHandler(event:FaultEvent):void
68     {
69        Alert.show("Error: " + event.fault.faultString, "Application Error");
70     }
71
72     public function changeImage(img:String):void
73     {
74         userImage.visible = true
75         userImage.source = "http://www.url.co.uk/wld/phonebook/" + img
76
     }
77
78 ]]>
79</mx:Script>
80
81<mx:Style>

82    .header {color: #70c7f1;}
83    .greyHeader {color: #777879;}
84    .controls {color: #000000; font-size: 13pt;}
85</mx:Style>

86
87     <mx:WebService id="popData" wsdl="http://www.url.co.uk/wld/services/phoneBook.cfc?wsdl" showBusyCursor="true" useProxy="false">

88 <mx:operation name="getData" fault="faultHandler(event)" result="resultsHandler(event)" />
89 </mx:WebService>
90
91     <mx:Fade id="fadeOut" duration="1.0" alphaFrom="1.0" alphaTo="0.0"/>
92 <mx:Fade id="fadeIn" duration="2000" alphaFrom="0.0" alphaTo="1.0"/>
93
94    <mx:Canvas id="outerCanvas" x="0" y="0" width="220" height="240" backgroundColor="#70c7f1" borderStyle="solid" cornerRadius="25" borderThickness="0">
95    
96        <mx:Canvas id="innerCanvas" x="10" y="22" width="200" height="210" backgroundColor="#FFFFFF" borderStyle="solid" cornerRadius="25" borderThickness="0">
97            
98            <mx:Label x="10" y="10" text="White label" id="header" styleName="header" fontWeight="bold"/>
99            <mx:Label x="78" y="10" text="Dating PhoneBook" styleName="greyHeader" fontWeight="bold"/>
100            <mx:DataGrid id="displayPeople" x="10" y="32" width="180" height="108" itemClick="changeImage(displayPeople.selectedItem.IMAGE)">
101                <mx:columns>
102                    <mx:DataGridColumn headerText="Name" width="140" dataField="NAME"/>
103                    <mx:DataGridColumn headerText="No." width="40" dataField="NO"/>
104                    <mx:DataGridColumn headerText="Img" width="40" dataField="IMAGE" visible="false"/>
105                </mx:columns>
106            </mx:DataGrid>
107            <mx:Image x="138" y="150" source="@Embed(source='wldLogoTiny.png')" />
108            <mx:Image x="25" y="144" toolTip="{displayPeople.selectedItem.NAME}" id="userImage" visible="true" showEffect="{fadeIn}" />
109        </mx:Canvas>
110        <mx:Label text="_" styleName="controls" toolTip="Minimize" x="173" y="-2" click="onMinimize()" />
111        <mx:Label text="X" styleName="controls" toolTip="Close" x="184" y="1" click="onClose()" />
112
113    </mx:Canvas>
114
115</mx:WindowedApplication>

PhoneBook screen shot