Home > Flash and Actionscript, Macromedia Flex > HTTP Authentication for HTTP/GET requests using ActionScript 3

HTTP Authentication for HTTP/GET requests using ActionScript 3

I am working on ActionScript3 API for Bloglines services, which requires HTTP Authentication for its two of the services. I was not able to set the header of a HTTP/GET request. Macromedia Flash Player allows you set the header only for POST requests. I discussed this issues with Ted Patrick and he told me how I can us Socket to achieve the desired and he was very kind to give a me code-snippet, which got me started. Thanks Ted.
Finally, I could implement a class(HTTPURLLoader) which allows me to:

  • Add request-headers
  • Do HTTP Authentication for GET URLs
  • Handle HTTP status messages
  • Read the complete response header

It basically connects to a HTTP server on port 80(hardcoded for now) and sends an HTTP/1.0 request so that server closes the connection immediately after response. I could use HTTP/1.1 to keep connection alive and do things. But then closing connection would require some more logic, either a timeout logic if there is no activity on socket then close the connection, or find the end delimiter of response and then close. So I chose the easiest approach :)
I am still working on it and there is a lot(bugs-fixing, optimization, code-commenting, removing hardcoded stuff etc) to be done. I just wanted to share whatever I have done so far. I think, idea is more important than the implementation.
Anyways, I also implemented Base64 in AS3 and also OPML parser for Bloglines. I would soon upload the entire Bloglines AS3 API source.
Download the code:
Usage:-

<mx:Application xmlns:mx="http://www.macromedia.com/2005/mxml" creationComplete="onAppInit()">
<mx:Script>
import flash.net.URLRequest;
import flash.net.URLRequestHeader;
import com.abdulqabiz.net.HTTPURLLoader;
import com.abdulqabiz.crypto.Base64;
private var loader:HTTPURLLoader;
private var END_POINT:String = "http://rpc.bloglines.com/";
//you need to set your email/password required for Bloglines access.
private var email:String = "YOUR_EMAIL_FOR_BLOGLINES";
private var password:String = "YOUR_BLOGLINES_PASSWORD";
private function onAppInit()
{
loader = new HTTPURLLoader();
loader.addEventListener("complete", onComplete);
loader.addEventListener("httpStatus", onHTTPStatus);
loader.addEventListener("progress", onProgress);
//for simplicity,not handling following three events.
//loader.addEventListener("close", onClose);
//loader.addEventListener("ioError", onIOError);
//loader.addEventListener("securityError",onSecurityError);
}
private function onComplete(event:Event)
{
//headers stroed as name-value(hash map)
var rh:Object = HTTPURLLoader(event.target).responseHeaders;
var str:String = "";
for(var p:String in rh)    str+= p + ":" + rh[p] + "\n";
console.text+="Response Headers: \n" + str + "\n\n";
//data property holds the content
console.text+="Body Content:\n" + HTTPURLLoader(event.target).data + "\n\n";
}
private function onProgress(event:ProgressEvent)
{
//bytesTotal is not accurate, and its 0 if server doesn't send Content-Length header.
console.text+= "Event: progress:-\n" + "bytesLoaded: " + event.bytesLoaded + "\n\n";
}
private function onHTTPStatus(event:HTTPStatusEvent)
{
//if httpStatus is 401, 403, 404, 500, 501, socket is closed.
console.text+= "Event: httpStatus (" + event.status + ")\n\n";
}
private function loadURL()
{
var request:URLRequest = new URLRequest();
//call listsubs method of Bloglines
request.url = END_POINT + "listsubs";
var credentials:String = Base64.encode(email + ":" + password);
//create HTTP Auth request header
var authHeader:URLRequestHeader = new URLRequestHeader("Authorization","Basic " + credentials);
//add the header to request
request.requestHeaders.push(authHeader);
//make the request.
loader.load(request);
}
</mx:Script>
<mx:Button label="Load URL" click="loadURL()"/>
<mx:TextArea id="console" width="100%" height="100%"/>
</mx:Application>
  1. Just me
    March 17th, 2006 at 07:56 | #1

    Code error: “falsh” should be “flash” on line 4

  2. March 17th, 2006 at 20:25 | #2

    Thanks dude. Fixed….
    The .as file for download was fine, it was typo while writing post :)
    Thanks again..
    -abdul

  3. March 22nd, 2006 at 15:33 | #3

    cool blog

  4. Serg @ Costa Rica
    March 27th, 2006 at 03:53 | #4

    Hello,

    I have a camera accesible worldwide like this:

    http://ip_address:port_number/CGI_script?url_params
    

    but it’s web console as well as it’s images are only accesible via HTTP BASIC AUTH. This is a problem because I want to make a SWF that given the username, password and url can login and control this camera. The tricky part is the CGI that returns a:

    Content-type: multipart/x-mixed-replace;
    boundary=--myboundary --myboundary
    Content-type: image/jpeg
    

    I don’t know how you call this – motion or streaming JPEG – but basically the CGI returns one JPEG concatenated to another and separated by a boundary. Parsing that JPEG with AS is problem #2 really. Problem #1 is looking for a way to HTTP authenticate with Actionscript 2.0 – is this possible?

    I already have made a PHP that HTTP autheticates and returns one frame of the JPEG and I can reload this every second or so in the SWF. The problem is this demands bandwidth from the server where the SWF resides rather than using the cameras own server ro feed the SWF with images as well as beign less efficient.

    The reason I’m picking your brain about this is (sorry!) that I only found a solution remotely close to the one I’m looking for in your blog (pity it’s for AS 3.0). If you could point me in the right direction I would be forever grateful. Thanks.

  5. March 28th, 2006 at 01:31 | #5

    Hi, Serg
    I can’t think of a solution in AS 2.0. You can not manipulate binary data in AS2. Where AS3.0, you can actually do what you are looking for.
    I understand your point, polling every second probably takes lots of bandwidth…
    I would surely think over this, if I come across some idea, I would share with you.
    -abdul

  6. Phil Anderson
    May 24th, 2006 at 13:12 | #6

    Hi Abdul,
    I apologize for this being kind of random, but I’m looking for some really good Flash Action Script Developers for a rich media-based start-up. I was wondering if you or anyone else is interested and is very proficient in Action Script and possibly Flex or Laszlo, to please send me an email at phils411@yahoo.com
    Thanks,
    Phil

  7. ajit parthan
    August 19th, 2006 at 01:30 | #7

    Hi Abdul,
    I am looking at a similar problem with slightly different twist. It is best described by a question posted here http://192.150.14.120/cfusion/webforums/forum/messageview.cfm?catid=582&threadid=1160651&enterthread=y
    “I would like a standalone Flex 2.0 SWF to be able to use a set of 3rd party webservices protected by basic authentication. Is it possible? If yes, could someone put a simple step-by-step example up? I just can’t see anyway to do this from the livedocs entry.”
    The stuff livedocs and other places seem to imply a Flex or CF server in the back-end.
    What you have could be used to address this but I am not able to get it to work with the WebService object. I am using your code to do basic HTTP authentication then invoke calls using the WebService object. Though the authentication suceeds I still get prompted for user/password when I make the WebService call.

  8. Phil
    December 14th, 2006 at 08:44 | #8

    Hi,
    I’m looking to connect to a web service that requires authentication. In order to authenticate, I need to pass an authentication token in the HTTP Request in the web service (Authentication: “Basic token_goes_here”).
    Has anyone ever done this before in ActionScript? I am totally puzzled! Help would be greatly appreciated.
    -phil

  9. December 14th, 2006 at 14:08 | #9

    @phil – If you are doing HTTP post from Flash Player you can use following:-
    Flash Player 7/8:
    public addRequestHeader(header:Object, headerValue:String) : Void
    Above method is available for XML and LoadVars objects
    Flash Player 9:-
    Check out these classes: URLRequestHeader, URLRequest, URLLoader…
    If you are making HTTP/GET request and wanna send custom headers as part of request, you can follow the technique mentioned in the POST, it would only work for Flash Player 9 onwards…
    BTW! Just looking at your comment again, I believe you are trying to bypass the HTTP Authentication to get access to WebService, if that is the case and you are targetting Flash Player 9, you can use the logic mentioned above (my post)…
    Hope that helps..
    -abdul

  10. December 19th, 2006 at 04:09 | #10

    Actually, AFAIK we can modify the header of GET request made by HTTPService by altering “headers” property.
    I saw Peter Farland advising on this subject here and I will test this inside my application in a matter of days.
    http://www.mail-archive.com/flexcoders@yahoogroups.com/msg48101.html
    Please correct me, if I am wrong.

  11. December 19th, 2006 at 11:24 | #11

    @Jabby – It might have been fixed, when I wrote this code it was not there. I did good investigation, even talked to Flash Player team..
    If it’s there then it’s good. HTTPService (without proxy) used URLRequest (URLRequestHeader etc), so this thing should be straight forward no need of my code…
    Cool..
    -abdul

  12. Markas Read
    December 20th, 2006 at 18:06 | #12

    There is an undocumented base64 encoder in as3 under mx.utils.base64Encoder (also base64Decoder). does anyone know the difference between drain() and flush()?

  13. December 20th, 2006 at 19:16 | #13

    @Markas – I heard from someone that there is undocumented Base64 but wasn’t sure where it was. I even asked someone in Adobe, but he was not also sure.
    Anyways, it’s always to good to see such classes part of frameworks, saves time and lets us focus on main logic.
    Thanks for your comment, it’s helpful.
    -abdul

  14. Steve
    February 14th, 2007 at 20:43 | #14

    Hi All,
    I have built a Flex front end that uses the webservice tag to communcate with an asp.net web service. The webservice works great and the app is simple amazing. My problem is that I want to use basic authentication to obtain the WSDL and make subsequent calls to the service’s methods. I tried setRemoteCredentials and setCredentials from within Flex on the webservice but neither work. Has anybody successfully called a webservice using basic authentication without a user name and password pop-up (its hard coded for now)? I have one generic user name and password setup to call the webservice over SSL. This is used for all users. I basically want to make the communication transparent to the user and still keep the webservice secure. any ideas? Thanks! -Steve

  15. February 19th, 2007 at 20:33 | #15

    @Steve – You can do one thing. You can use the technique mentioned (above) in this post to establish connection (authenticate) before calling loadWSDL (..) method of WebService.
    I believe, once HTTP Authentication session is established before the Webservice call, you would not be asked to validate in entire session?
    You can try loading WSDL using HTTPURLLoader (above). Later you can use WebService…
    Hope that works
    -abdul

  16. March 1st, 2007 at 00:24 | #16

    Hi,
    I am going to put a new version soon. That fixes some issues and more optimized. I am also looking into possibility to invoke more HTTP methods (PUT, HEAD etc)…

  17. Matt Lins
    March 3rd, 2007 at 22:34 | #17

    Abdul,
    This looks really cool. It’s perfect for a RoR project I’m working on. I’m anxious to see the updated code!
    Thanks.

  18. Paul
    April 3rd, 2007 at 20:04 | #18

    This code looks really promising. I am actually a Flash noob, but a javascript guru ;) XMLHttpRequest (many call it AJAX) is implemented in many browsers, but plenty lack the option of authentication. That’s why I am looking around in Flash land.

    Basic authentication, though, sends username and password in plaintext over the wire. I use Digest authentication for that reason. I wrote an entire PHP class to tackle that on server-side. If you want I can send info on the protocol so maybe you can fix some of the Flash part? Would make me really happy :D

  19. April 3rd, 2007 at 20:52 | #19

    @Paul: Thanks, I would love to see your code. I can add this feature in this class. I am working on it to add many new features (support for more HTTP methods HEAD/PUT etc, http-status (redirection handling etc)..
    Thanks
    -abdul

  20. Jeremy
    April 6th, 2007 at 02:13 | #20

    How do I get this to work with an https URL?
    I keep getting:
    Error #2044: Unhandled ioError:. text=Error #2031: Socket Error. URL: https://MYURL

  21. April 6th, 2007 at 19:04 | #21

    @Jeremy: Currently there is no support for HTTPS. I am basically creating Socket connection over port 80. For HTTPS, I have to implement HTTP over TLS.
    I want to add all features in my libraries it’s just I am always busy with something at my full time job :)
    However, I would check it out..
    Thanks for your feedback.
    -abdul

  22. April 27th, 2007 at 17:17 | #22

    Would it be possible to use the ideas from this class to write a replacement for HTTPService that didn’t suffer from these limitations:
    http://tech.groups.yahoo.com/group/flexcoders/message/54976

    e.g. a class which could connect to any HTTP server and execute GET, POST, PUT and DELETE requests. I am building something at the moment which interacts with a RoR powered web service which requires this functionality. I currently have it working through a PHP proxy but it seems a little dirty…

    Thanks for your work on this,

    Kelvin :)

  23. April 28th, 2007 at 01:46 | #23

    @Kevin: Thanks for your comment. I am not sure if HTTPService without Proxy can set headers for a HTTP GET because it uses URLLoader internally, AFAIK.
    I think, HTTPURLLoader can be used for other HTTP methods (HEAD, PUT etc). That’s something I am working on but I am busy at my fulltime job also it’s taking more time.
    It would be great, if you or someone can investigate this. I have created a Google Project “as3httpclient” for these things. Where we can create different classes for dealing things which Flash Player cant.
    Since I am using Binary Socket here, it’s totally feasible to do anything as long as we are able to implement HTTP/HTTPS protocol spec(rfcs).
    Please look at it. Please feel free to let me know your thoughts/inputs either here or you can use project mailinglist or my email (mail at abdulqabiz.com), whichever is comfortable to you…
    Project: http://code.google.com/p/as3httpclient/
    Blog post: http://www.abdulqabiz.com/blog/archives/flash_and_actionscript/actionscript_3_httpc.php
    Thanks
    -abdul

  24. pinder
    May 3rd, 2007 at 13:13 | #24

    Hi Abdul,
    Would your as3httpclient/HTTPURLLoader code work with a Flash CS3 created SWF?
    I’m trying to implement your HTTPURLLoader code in Flash CS3 for Flash 9 player. I’m trying to build a SWF that would communicate with a REST service. Conceivably, it would do a POST to a REST service for authentication and it would receive tokens in the response headers and all subsequent calls to the service would send that token in the header of the GETs.
    I’ve been trying to implement this but with no luck. I’ve noticed a lot of subtle inconsistencies between Apollo and CS3 Actionscript3.
    For example Apollo’s HTTPStatusEvent supports responseHeaders but the Flex/CS3 version does not.
    Do you know if it’s even possible to do the RESTful communication with a CS3/Flash9 actionscript 3 SWF? Or would this work for Apollo only?

  25. May 3rd, 2007 at 23:35 | #25

    @pinder:
    > Would your as3httpclient/HTTPURLLoader code work
    > with a Flash CS3 created SWF?
    Yup! It’s written in ActionScript 3, so it would work for Flash Player 9, no matter what tool you use to compile your app. In this case, it’s Flash CS3.
    > Conceivably, it would do a POST to a REST
    > service for authentication and it would receive
    > tokens in the response headers and all
    > subsequent calls to the service would send that
    > token in the header of the GETs.
    You can use URLLoader for authentication. For later calls, you can use HTTPURLLoader. I am working on a new version of HTTPURLLoader, that would allow you to do POST also. If you want to use HTTPURLLoader for POST, you can look into code and remove the hardcoded “GET” to request.method..
    > I’ve been trying to implement this but with no
    > luck. I’ve noticed a lot of subtle
    > inconsistencies between Apollo and CS3
    > Actionscript3.
    I have not yet used Flash CS3, but I can imagine there might be difference in flex framework but you should be able to use Flash Player 9 APIs…
    > For example Apollo’s HTTPStatusEvent supports
    > responseHeaders but the Flex/CS3 version does
    > not.
    Apollo has better APIs for flash.net.* classes.
    > Do you know if it’s even possible to do the
    > RESTful communication with a CS3/Flash9
    > actionscript 3 SWF? Or would this work for
    > Apollo only?
    Yeah, without any problem. For REST, you have to just use URLLoader and related classes for REST…

  26. blaze
    May 11th, 2007 at 05:41 | #26

    Very cool, but you need to rig the backend server to handle XMLSocket in order to connect to port 80 from flash.
    Really limits the use of this unfortunately. I wish Adobe would give us port 80 access via regular crossdomain xml

  27. Guojian
    May 20th, 2007 at 03:15 | #27

    Would it be possible to use this to upload a ByteArray? Would love to be able to upload an Image as ByteArray over HTTP without having to Base64.encode/decode

  28. Erik
    May 26th, 2007 at 05:29 | #28

    @Blaze
    Yes, that would be possible. I currently have an example that uploads a file using this method including authentication on another then the default port.
    Abdul,
    I’ve have taken your idea and written my own class. This class supports other ports, aithentication, get / set and multipart messages. If you are interested in this, please let me know.
    Greetz EE

  29. May 26th, 2007 at 16:26 | #29

    @Eric: Sure, would love to look at it, if you are interested you can contribute it to as3httpclient Google project. In any-case, you can email to me at [mail at abdulqabiz.com]
    Thanks
    -abdul

  30. saravanan
    June 19th, 2007 at 21:59 | #30

    I want to read the http response from a urlrequest, so that I can handle the errors in a more customized manner. your article on ” HTTP Authentication for HTTP/GET requests using ActionScript 3″ was really nice. HTTPURLLOader doesn’t comes along with flex as a component or a property, so how will I be able to use it

  31. August 31st, 2007 at 02:20 | #31

    Thanks! This is just the sort of thing I’ve been looking for.

  32. Thiago
    November 8th, 2007 at 18:24 | #32

    Hello,
    Your script worked for me. But even when I got authenticated, It shows a popup asking for password.
    How can we get rid of it?
    Is it hard coded in the binary flash file?

  33. Caspar Harmer
    November 9th, 2007 at 06:39 | #33

    Hi Abdul,
    Just wondering if you had a newer version than the one you posted to Google groups.
    Great job, btw.

    Casp

  34. David Bates
    November 29th, 2007 at 20:28 | #34

    I really want to download your code, but the ZIP file just appears empty!
    I can’t believe how hard it has been trying to find an answer to this…

  35. David Bates
    December 3rd, 2007 at 17:26 | #35

    I’ve got the code and been playing with it, but I can’t get it to work with mx:WebServices. Has anybody got this work? Are there any examples?
    Cheers,
    David.

  36. tcherkezian
    January 14th, 2008 at 20:17 | #36

    Is your component can read headers httpS (with ssl). We just need to read the code response and the cookies names and values.
    Thank you very much.

  37. January 14th, 2008 at 21:40 | #37

    @tcherkezian: No it doesn’t support SSL…I have been thinking to add it…
    -abdul

  38. Jeremy
    February 4th, 2008 at 23:42 | #38

    any luck with the https portion of your library. I would be willing to help build out this portion if you’ve started or have a plan

  39. ebaggg
    April 8th, 2008 at 02:43 | #39

    Do you have any ideas why this is not working with HTTP 1.1? The socket receives the request and returns the response, but does not close the socket. It hangs for a 5 seconds before the connection is just closed. I tried different variations of the end bytes (2 lines) but nothing seems to work and I can’t find anything in the specs.

  40. April 20th, 2008 at 02:34 | #40

    whats a url please tell me

  41. June 11th, 2008 at 11:28 | #41

    I’m trying to connect to a service endpoint that requires HTTP Basic Auth.
    The Flex library implements setCredentials() on HTTPService as unsupported, for reasons I don’t really grok.
    After much digging, I tried the technique discussed in this blog posting, but with no success.
    After tracing through the Flex HTTP service stack, I finally realized that I could simply do the following in my initialization code before making a call on my service object:

    ...
    addAuthHeader(myservice, "user", "pass");
    ...
    private function addAuthHeader(serv:*, username:String, password:String):void
    {
    //add the header to request
    var encoder : Base64Encoder = new mx.utils.Base64Encoder();
    encoder.encode(username + ":" + password);
    serv.headers["Authorization"] = "Basic " + encoder.toString();
    }
    

    Works fine for direct, authenticated, access from my Flex 3 app to my backend service without any need for BlazeDS or other middleman proxy strategy.
    Works whether I’m using http: or https: to access the service.
    Hopefully, this comment will help others.

  42. Ridibona
    July 14th, 2008 at 04:41 | #42

    Hello everyone
    I am trying to use a MapPoint web service for virtual earth maps via Action script 2.0.
    1.) How do we do digest authentication in action script 2.0. Can someone provide me an example or code sample ?
    2.) MapPoint service exposes complex objects to deal with Route calculation etc.. ? Can Webservice class in AS 2.0 access such complex type objects ? What is the work around ?
    3.) Is Flash remoting better to talk to web services than the webservice class and XML connector?
    Thanks,
    Ridibona

  43. August 10th, 2008 at 17:46 | #43

    Hi cody,
    I have tried using ordinary serv.headers['Authorization'], but It didn’t work with me when method is “GET” !!
    Can you send the full httpservice code you made ?
    Thanks in advance

  44. SiggeLund, Sweden
    August 26th, 2008 at 15:45 | #44

    Hey,
    I did a modification on your class to get Basic Authentication working.
    The command request.requestHeaders.push(authHeader) causes an Error since it is not allowed to set the keyword Authorization any more.
    The solution I used was to let the constructor recieve a URLRequest object the same way as before, but the load method now recieves an Array of Strings instead. Each string in the format HeaderName:HeaderValue.
    I then adjusted your sendHeaders method to fetch the headers from the array instead. Worked fine, even with Authorize.
    If you wanna talk about it, drop me an email.

  45. February 13th, 2009 at 00:31 | #45

    Thank you for writing this very useful code, Abdul!

  46. March 7th, 2009 at 01:57 | #46

    Hi Guys
    This code was written long time back, things have changed a lot in Flash Player after that. Some of the headers were not allowed in some intermediate player releases, it seems Flash Player 10 has got those fixes.
    However, I am not still not sure one can do HTTP Auth over HTTP/GET in Flash Player 10.
    There is better library available now at http://code.google.com/p/as3httpclientlib, you might want to use it instead.
    I have stopped updating this code, after I noticed as3httpclientlib is good stuff.
    Sorry for delays in my reply, been stuck and shame on me, couldn’t be of any help when you needed.
    Thanks
    -abdul

  47. David W
    April 1st, 2009 at 03:49 | #47

    Abdul:
    The as3httpclientlib requires com.adobe.net.URI, but, this is not documented as to where to obtain this library. It’s not in Flex, it’s not AIR only?
    Seems this would be noted somewhere on the examples/docs, as the package seems unusable without this code.
    Thanks.

  48. April 1st, 2009 at 18:31 | #48

    @David
    I guess, it’s part of as3corelib (http://code.google.com/p/as3corelib/)
    Thanks
    -abdul

  49. zeeshan
    June 8th, 2009 at 23:40 | #49

    Hi Abdul,

    is it possible to add a custom header user_agent in httpservice?
    i had API.as class which requires a post method with custom header user_agent and user_agetn_id. i can add user_agent_id but i got ArgumentError on user_agent.
    can u please advise any solution?

    • June 9th, 2009 at 16:11 | #50

      @zeeshan: Did you try adding it to headers object? What error you get? I know, Flash Player doesn’t let you add/override many http-headers. As far as I know, none of headers (user_agent, user_agent_id) is standard http header, hence it should work.

      Please note, user-agent is a standard http header, if you are using user-agent, you might not be able to do that. Kindly check the list of http headers Flash Player doesn’t let developers override.

      -abdul