I was integrating a JQuery plugin for file uploads, uploadify, in my app when I saw a very strange behavior. The plugin reported an error transmitting the file to the server and debugging the controller code I noticed the target action wasn’t being called at all. Debugging the client code I found out that the server was redirecting the upload to the login page. The Controller was marked with the AuthorizeAttribute but the user was already authenticated. After a google search I found this article explaining the problem and a workaround that didn’t work for me.
One easy solution was to remove the Authorize attribute from that action but that would open a big security hole, allowing anybody to upload files to the server. I finally implemented a manual authentication that seems to work fine.
In the client I extract the value from the forms authentication cookie and send it with my file as data:
1: var auth = "<% = Request.Cookies[FormsAuthentication.FormsCookieName]==null ? string.Empty : Request.Cookies[FormsAuthentication.FormsCookieName].Value %>";
2:
3: //File upload
4: $('#photoUpload').fileUpload({
5: uploader: '/Content/uploader.swf',
6: script: '/Files/UploadPicture',
7: scriptData: { token: auth },
8: cancelImg: '/Content/images/cancel.png',
9: auto: true,
10: folder: '/uploads',
11: fileDesc: 'Image',
12: fileExt: '*.jpg;*.jpeg;*.png;*.gif'
13: });
14:
I think this technique could be easily applied to SWFUpload as well.
The server receives the security token so I needed to authenticate it. This action does the trick:
1: public ActionResult UploadPicture(string token, HttpPostedFileBase fileData)
2: {
3: FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(token);
4: if(ticket!=null)
5: {
6: var identity = new FormsIdentity(ticket);
7: if(identity.IsAuthenticated)
8: {
9: /*************************************
10: *
11: * HANDLE FILE
12: *
13: * ***********************************/
14: return Content("OK");
15: }
16: }
17: throw new InvalidOperationException("The user is not authenticated.");
18:
19: }
20:
I think I’ll move the authentication to an action filter to keep the action code cleaner but this works fine for now.