Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flex 3 - how to support HTTP Authentication URLRequest?

I have a Flex file upload script that uses URLRequest to upload files to a server. I want to add support for http authentication (password protected directories on the server), but I don't know how to implement this - I assume I need to extend the class somehow, but on how to I'm a little lost.

I tried to modify the following (replacing HTTPService with URLRequest), but that didn't work.

private function authAndSend(service:HTTPService):void{        
   var encoder:Base64Encoder = new Base64Encoder();        
   encoder.encode("someusername:somepassword");        
   service.headers = {Authorization:"Basic " + encoder.toString()};
   service.send();
}

I should point out that I'm not knowledgeable when it comes to ActionScript / Flex, although I have managed to successfully modify the upload script somewhat.

[Edit] - here is an update of my progress, based on the answer below, although I still cannot get this to work:

Thank you for your assistance. I've tried to implement your code but I've not had any luck.

The general behaviour I'm experiencing when dealing with HTTP authenticated locations is that with IE7 all is well but in Firefox when I attempt to upload a file to the server it displays an HTTP authentication prompt - which even if given the correct details, simply stalls the upload process.

I believe the reason IE7 is ok is down to the the session / authentication information being shared by the browser and the Flash component - however, in Firefox this is not the case and I experience the above behaviour.

Here is my updated upload function, incorporating your changes:

private function pergress():void 
{
if (fileCollection.length == 0) 
  {
  var urlString:String = "upload_process.php?folder="+folderId+"&type="+uploadType+"&feid="+formElementId+"&filetotal="+fileTotal;
  if (ExternalInterface.available) 
    {
    ExternalInterface.call("uploadComplete", urlString);
    }
  }
if (fileCollection.length > 0) 
  {
  fileTotal++;
  var urlRequest:URLRequest = new URLRequest("upload_file.php?folder="+folderId+"&type="+uploadType+"&feid="+formElementId+"&obfuscate="+obfuscateHash+"&sessidpass="+sessionPass);
  urlRequest.method = URLRequestMethod.POST;
  urlRequest.data = new URLVariables("name=Bryn+Jones");
  var encoder:Base64Encoder = new Base64Encoder();
  encoder.encode("testuser:testpass");
  var credsHeader:URLRequestHeader = new URLRequestHeader("Authorization", "Basic " + encoder.toString());
  urlRequest.requestHeaders.push(credsHeader);

  file = FileReference(fileCollection.getItemAt(0));
  file.addEventListener(Event.COMPLETE, completeHandler);
  file.addEventListener(HTTPStatusEvent.HTTP_STATUS, onHTTPStatus);
  file.addEventListener(ProgressEvent.PROGRESS, onUploadProgress);
  file.upload(urlRequest);
  }
}

As stated above, I seem to be experiencing the same results with or without the amendments to my function.

Can I ask also where the crossdomain.xml should be located - as I do not currently have one and am unsure where to place it.

like image 650
BrynJ Avatar asked Feb 03 '09 22:02

BrynJ


People also ask

What is urlsourcerequest in Salesforce?

sourceRequest: URLRequest — An URLRequest object that has already been requested and was redirected. The redirected URL will be used to substitute for part of the URL of this URLRequest object.

What is the urlrequest class?

The URLRequest class captures all of the information in a single HTTP request. URLRequest objects are passed to the load () methods of the Loader, URLStream, and URLLoader classes, and to other loading operations, to initiate URL downloads. They are also passed to the upload () and download () methods of the FileReference class.

What kind of data does the urlrequest API support?

The URLRequest API offers binary POST support and support for URL-encoded variables, as well as support for strings. The data object can be a ByteArray, URLVariables, or String object. The way in which the data is used depends on the type of object used:

Are custom HTTP request headers supported for GET requests?

Due to browser limitations, custom HTTP request headers are only supported for POST requests, not for GET requests. The URL to be requested.


4 Answers

The syntax is a little different for URLRequest, but the idea's the same:

private function doWork():void
{
    var req:URLRequest = new URLRequest("http://yoursite.com/yourservice.ext");
    req.method = URLRequestMethod.POST;
    req.data = new URLVariables("name=John+Doe");

    var encoder:Base64Encoder = new Base64Encoder();        
    encoder.encode("yourusername:yourpassword");

    var credsHeader:URLRequestHeader = new URLRequestHeader("Authorization", "Basic " + encoder.toString());
    req.requestHeaders.push(credsHeader);

    var loader:URLLoader = new URLLoader();
    loader.load(req);
}

A couple of things to keep in mind:

  • Best I can tell, for some reason, this only works where request method is POST; the headers don't get set with GET requests.

  • Interestingly, it also fails unless at least one URLVariables name-value pair gets packaged with the request, as indicated above. That's why many of the examples you see out there (including mine) attach "name=John+Doe" -- it's just a placeholder for some data that URLRequest seems to require when setting any custom HTTP headers. Without it, even a properly authenticated POST request will also fail.

  • Apparently, Flash player version 9.0.115.0 completely blocks all Authorization headers (more information on this one here), so you'll probably want to keep that in mind, too.

  • You'll almost surely have to modify your crossdomain.xml file to accommodate the header(s) you're going to be sending. In my case, I'm using this, which is a rather wide-open policy file in that it accepts from any domain, so in your case, you might want to limit things a bit more, depending on how security-conscious you are.

crossdomain.xml:

<?xml version="1.0"?>
<cross-domain-policy>
    <allow-access-from domain="*" />
    <allow-http-request-headers-from domain="*" headers="Authorization" />
</cross-domain-policy> 

... and that seems to work; more information on this one is available from Adobe here).

The code above was tested with Flash player 10 (with debug & release SWFs), so it should work for you, but I wanted to update my original post to include all this extra info in case you run into any issues, as the chances seem (sadly) likely that you will.

Hope it helps! Good luck. I'll keep an eye out for comments.

like image 138
Christian Nunciato Avatar answered Oct 12 '22 13:10

Christian Nunciato


The FileReference.upload() and FileReference.download() methods do not support the URLRequest.requestHeaders parameter.

http://livedocs.adobe.com/flex/2/langref/flash/net/URLRequest.html

like image 40
Steven Mo Avatar answered Oct 12 '22 14:10

Steven Mo


If you want to upload a file, you just need to send the correct headers and the content of file using URLRequest via UploadPostHelper class. This works 100%, i am using this class to upload generated images and CSV files, but you could upload any kind of file.

This class simply prepares the request with headers and content as if you would be uploading the file from a html form.

http://code.google.com/p/as3asclublib/source/browse/trunk/net/UploadPostHelper.as?r=118

_urlRequest = new URLRequest(url);
        _urlRequest.data = "LoG";
        _urlRequest.method = URLRequestMethod.POST; 

        _urlRequest.requestHeaders.push(new URLRequestHeader("X-HTTP-Code-Override", "true"));
        _urlRequest.requestHeaders.push(new URLRequestHeader("pragma", "no-cache"));

        initCredentials();
_loader.dataFormat = URLLoaderDataFormat.BINARY;
            //this creates a security problem, putting the content type in the headers bypasses this problem
            //_urlRequest.contentType = 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary();
            _urlRequest.requestHeaders.push( new URLRequestHeader( 'Cache-Control', 'no-cache' ) );
            _urlRequest.requestHeaders.push(new URLRequestHeader('Content-Type', 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary()));
            _urlRequest.data = UploadPostHelper.getPostData("file.csv", param[1]);

        _loader.load(_urlRequest);
like image 25
Caius Miron Avatar answered Oct 12 '22 13:10

Caius Miron


I'm not sure about this but have you tried adding username:password@ to the beginning of your url?

"http://username:[email protected]/yourservice.ext"

like image 34
Leo Jweda Avatar answered Oct 12 '22 15:10

Leo Jweda