4

I'm trying to use Uploadify, an Ajax file uploader, with Play Framework.

Uploadify uses a Flash object to talk to the server ... so by default it will not use the Play cookies. I want to authenticate my user correctly, so I need to get uploadify to send some cookies over itself.

Does anyone has a working example of the two working together, or, failing that, some pointers?

ripper234
  • 222,824
  • 274
  • 634
  • 905
  • It's worth noting that this if you're using `httpOnly`, it is probably not possible to use Play's standard auth this way. I'm considering dropping `httpOnly`. – ripper234 Mar 22 '12 at 08:43
  • 1
    Also, related questions that details similar issues with Uploadify in other web frameworks: http://stackoverflow.com/questions/1729179/uploadify-session-and-authentication-with-asp-net-mvc and http://stackoverflow.com/questions/1284666/sessions-and-uploadify – ripper234 Mar 22 '12 at 08:51

2 Answers2

0

uploadify has an option called scriptData which you could used to send your authentityToken:

#{authenticityToken /}

<script>
var token = $('#input[name=authenticityToken]').val();
$('#file_upload').uploadify({
  'uploader'    : '/uploadify/uploadify.swf',
  'script'      : '/uploadify/uploadify.php',
  'cancelImg'   : '/uploadify/cancel.png',
  'folder'      : '/uploads',
  'scriptData'  : {'authenticyToken': token}
});
</script>
ripper234
  • 222,824
  • 274
  • 634
  • 905
Gelin Luo
  • 14,035
  • 27
  • 86
  • 139
  • I know about scriptData. So are you saying that there is already a hidden input field named `authenticityToken` generated by Play? I thought the session was handled via a cookie. – ripper234 Jan 25 '12 at 08:07
  • Ah, you mean using http://www.playframework.org/documentation/current/tags#authenticityToken. It's also worth mentioning the builtin `#{form}` tag adds this automatically. http://www.playframework.org/documentation/current/tags#form – ripper234 Jan 25 '12 at 08:55
  • That's not enough, at least not with the Secure module (e.g. `Secure.checkAccess()` needs `username` to be in the session). Perhaps I should copy the entire session cookie as well? Not sure how I would do that though. – ripper234 Jan 25 '12 at 09:04
  • Put whatever you need into the scriptData. uploadify uses flash to upload files. Unfortunately flash has no access to browser session, at least it won't send through the cookie on the wire. – Gelin Luo Jan 26 '12 at 08:22
0

Well, if you're using httpOnly configuration (and you should!), then it's impossible to pass Play's native auth cookie to uploadify.

What I did was:

1. Not secure the Images controller with @With(Secure.class), but instead use a before method:

@Before(unless = "uploadPost")
public static void before() throws Throwable {
    Secure.checkAccess();
}

2. Pass along two parameters from the controller that renders the page hosting the uploadify plugin: userId, and signedUserId

String userIdSignature = Crypto.sign(Long.toString(user.id));
render(..., user.id, userIdSignature);

3. Pass these two parameters to uploadify, and to the uploadPost method

public static void uploadPost(Upload upload, long userId, String userIdSignature) {
    assertEquals(userIdSignature, Crypto.sign(Long.toString(userId)),
        "Failed to authenticate user ID " + userId);

If for some reason you don't want the client to know its user ID, an alternative to signing is encrypting the user id.

Note that you are still exposed to replay attacks using this method, but I believe this is a general problem with Play (I could be mistaken about this). You can add an expiration date to the signature to limit the damage.

ripper234
  • 222,824
  • 274
  • 634
  • 905