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>
  • Just me
    Code error: "falsh" should be "flash" on line 4
  • Thanks dude. Fixed....
    The .as file for download was fine, it was typo while writing post :)
    Thanks again..
    -abdul
  • cool blog
  • Serg @ Costa Rica
    Hello,



    I have a camera accesible worldwide like this:

    http://ip_address:port_number/CGI_script?url_pa...

    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.

  • 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
  • Phil Anderson
    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
  • ajit parthan
    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/m...
    "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.
  • Phil
    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
  • @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
  • 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@yahoogro...
    Please correct me, if I am wrong.
  • @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
  • Markas Read
    There is an undocumented base64 encoder in as3 under mx.utils.base64Encoder (also base64Decoder). does anyone know the difference between drain() and flush()?
  • @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
  • Steve
    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
  • @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
  • 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)...
  • Matt Lins
    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.
  • Paul
    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

  • @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
  • Jeremy
    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
  • @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
  • 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 :)

  • @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_a...
    Thanks
    -abdul
  • pinder
    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?
  • @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...
  • blaze
    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
  • Guojian
    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
  • Erik
    @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
  • @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
  • saravanan
    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
  • Thanks! This is just the sort of thing I've been looking for.
  • Thiago
    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?
  • Caspar Harmer
    Hi Abdul,

    Just wondering if you had a newer version than the one you posted to Google groups.

    Great job, btw.





    Casp

  • David Bates
    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...
  • David Bates
    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.
  • tcherkezian
    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.
  • @tcherkezian: No it doesn't support SSL...I have been thinking to add it...
    -abdul
  • Jeremy
    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
  • ebaggg
    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.
  • cody karpf
    whats a url please tell me
  • 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.

  • Ridibona
    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
  • Mahmoud Khaled
    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
  • SiggeLund, Sweden
    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.
  • Thank you for writing this very useful code, Abdul!
  • 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
  • David W
    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.
  • @David
    I guess, it's part of as3corelib (http://code.google.com/p/as3corelib/)
    Thanks
    -abdul
  • zeeshan
    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?
  • @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
  • ab
    I need the code for HTTP POST and GET. i basically what to send a url to server and check the status,display the response by server…..and calculate the time taken to get the response.
    I am using cs4/actionscript 2.0

    can you help me……
  • marc
    nice work.... very useful....
  • venkatn
    i am trying to upload files using fielreference.upload(). how do i use basic authentication using as3 script i dont find Base64 in as3 api.

    i have gone through the livedocs help . its mentioned that with filereference , urlrequestheader does not work . is that true.

    i cant use u r example because i dont find api classes.

    abdul please help me
  • Ravi Shankar
    Hi,

    Excellent, I am new to FLEX n I am doing a project while learning. This example was really helped me as my situation required this solution.

    I need to access local filesystem using FLEX web application, could you help me out to solve this problem or any alternative solution will be appreciated. As I know FLEX (WEB) should not support filesystem access.

    Thanks a lot,
    Ravi Shankar
  • Hi Ravi

    As far as I know, Flash Player 10 allows local file access (read-only). You can prompt user to browse a file and content of that can be read in actionscript. I don't think, you can write to client machine without using any signed-code (applet, activex, javascript, etc).
  • Hi Ravi

    As far as I know, Flash Player 10 allows local file access (read-only). You can prompt user to browse a file and content of that can be read in actionscript. I don't think, you can write to client machine without using any signed-code (applet, activex, javascript, etc).
  • Ravi Shankar
    Yes, I think you might be right. I know about flash.net.FileReference class and I have used earlier in my code.

    I have tried to use JScript but I am not an expert in that. I am planning to use Java/.Net code with Flex Remoting. If you don't mind could you give me a sample on JScript which creates/deletes a file. This will really help to avoid the dependencies.

    Thanks,
    Ravi Shankar
  • suprasannachoudhury
    I have always used 'xmlns:mx="http://www.adobe.com/2006/mxml" ' instead of

    'xmlns:mx="http://www.macromedia.com/2005/mxml"' .And the later one doesnt produce a result also.. can you suggest ..
    And one more thing is , i 'm not able to ship a weather webservice out side flex builder .Its giving 'security error accessing url' . Even i ahve added crossdomain policy file also
blog comments powered by Disqus