We have a c# asp.net web application that, amongst other things, allows users to download previously uploaded files such as PDF's, Word docs etc. The asp.net app is served up via an IIS6 server and the file resources live on a different server.
When the user requests a file (i.e. click a button on the web form), we stream the file back to their browser, changing the ContentType appropriately.
This seemed a good way to avoid going down the IIS virtual folder route to serve up the file resources - which we had concerns about due to the potential for users to hack the URL. i.e. with a URL like https://mydomain/myresource/clientid/myreport.docx, a savvy user could have a good stab at guessing alternative cvlientid's and document names.
The trouble with streaming a Word document to the browser is that when the browser throws it at Word, Word treats it as a brand new doc, which means the original document's properties & margin info is lost.
Our users store metadata information in the Word doc properties, so this solution is not acceptable to them.
Serving up via IIS virtual folders solves that problem, but introduces the URL security problem.
So my questions are ...
Does anyone know how we can use URL encryption/decryption (or obfuscation) with IIS Virtual folders?
Or does anyone know of any open source projects that do a similar job.
Or does anyone have any sugestions on how to go about writing our own implementation of Virtual folders but with encrypted URLs?
Many thanks in advance.
ps. our web app is delivered over https
Sorry guys, in my question, I have made some incorrect assumptions.
What am I trying to do is persist the properties stored on a word document when they are delivered from server (using either Response.TransmitFile or via a virtual folder) to a client browser.
I set up a test scenario with an IIS virtual folder and dropped a docx file (that I know contains info in the title & subject properties) in my virtual folder's physical path.
I pointed my browser at the virtual folder alias and the browser popped up its message to either open or save the doc.
If I choose to save it, the saved docx still has the properties intact.
If I choose to open it fist and then save it from Word, the saved docx has lost the properties.
So I think I need to post a different question!
You may find that the ClaimsAuthorizationManager class in "Windows Identity Foundation" does what you want. You get to implement whatever logic you like to determine who can download what without using "directory security".
Related
We have a DNN based websites being used for our company. Within that there are multiple sites among which there is a site at https://example.com/siteId25.
This particular site have been modified by any one of the Admin's in such a way that upon visiting that url, its only downloading a document(.docx) file rather then showing the website which used to be there.
The file is within the hosted website's portal folder at path "wwroot/WebsiteFolder/Portal/25/Info siteId25.docx". Upon removing that file, it starts giving error.
We already have Testing version of that site on a different server, which is serving appropriate website page upon visiting that path.
Upon checking the Site settings in the Website Persona Bar, as well as checking that in the database table Portal Settings, we didn't found any relevant settings to serve document rather then webpage.
All of the settings are having same values default values in both production & in Testing environment. We tries switching Site Alias mapping mode from canonical to direct, but issue persist.
Can anyone please tell us any to set back url to show website rather then download file?
You find the start page in the table PortalLocalization. The value in the field HomeTabId is the TabId from the table Tabs (pages were called tabs in DNN in former times).
Mind the field PortalId, and CultureCode (if you have a multilingual portal). Set the value to the TabId needed (mind the PortalId also in the table Tabs).
After changing anything in the databse, you should always restart the application pool in IIS. If you have no other way to do it, just open the web.config file with a text editor, enter a blank line, delete this line and save the file.
I've got an ASP.NET site which allows users to view/open files from a shared network folder via links which call response.redirect passing in the full location of the relevant file (using a mapped drive value on appserver, not specific server name).
This works fine in IE7 but now w're doing a Win7 upgrade it isn't working in IE9 (or Chrome). For IE9 it displays basic "Internet Explorer cannot display the webpage" message.
I've tried changing it to pass in the path using server instead of mapped drive but that's worse, is tries to start at root of application directory and then acts as if server is a folder within it (and displays "The page cannot be found").
The site probably shoudln't have ever been designed in this way but I need a dirty workaround, no time for complete redesign. Any ideas? If the cause is how newer browsers handle the redirect response is it possible to alter an advanced setting to mimic previous version? I've tried adding site as trusted and also compatibility view.
Sample code:
Response.Redirect("R:\SharedFolder\indexedEmail.msg"); //Where R is mapped to netshare
Try using using the file:// URL prefix. The newer browsers may not be assuming that the URL is pointing to the local file system.
I'm working on a continuing API project. The current issue at hand is to be able to download my data from the AtTask server in precisely the folder structure they exist in on the AtTask servers. I've got the folder creation working nicely; the data types between Document, Document Folder and Document Version seem to be pretty clear. I am a little disillusioned about the fact that extension isn't in the document object (that I have to refer to the document VERSION for that)... but I can see some of the reason for that from a design perspective.
The issue I'm running into now is that I need to get the file content. I originally through from the API documentation that I'd be able to get to the file contents the same way as the documentation recommends uploading it -- through the handle. Unfortunately, neither document nor docv seem to support me accessing the handle except to write a new file.
So that leaves me the "download URL" as the remaining option. If I build the UI strings from the API calls using my browser, I get a URL with https://attaskURL/document/download?ID=xxxx (and can also get the versionID and such). If I paste the url into the browser where I'm logged in to the user interface of AtTask, it works fine and I can download the file. If, instead, I use my C# code to do so, I get the login page returned as a stream for me to download instead of my actual file because I'm not authenicated. I've tried creating a network credential and attaching it to the request with the username and password, but to no avail.
I imagine there's a couple ways to solve this problem -- the easy one being finding a way to "log in" to the download site through code (which doesn't seem to be the usual network credential object in C#) OR find a way to access the file contents through the API.
Appreciate your thoughts!
It looks like you can use the download URL if you put a session id in the URL. The details on getting a session id are here (basically just call login and a session id is returned in JSON):
http://developers.attask.com/api-docs/#Authentication
Then cram it on the end of your document download URL:
https://yourcompany.attask-ondemand.com/document/download?ID=xxxx&sessionID=abc1234
I've given this a quick test and I'm able to access a document.
You can use the downloadURL and a sessionID IF you are not using SAML authentication.
I have tried it both ways and using SAML will redirect you to the login page.
The general problem: I have some code that needs a URL to a PDF file. It seems to work for URLs I find online, but not the ones I create myself.
For example, when I use a random URL from Xamarin it works fine, but when I try to generate a URL from either DropBox or Amazon Cloud Drive it does not work.
Example URLs:
These links open harmless PDF files. Please try it:
Xamarin (works fine)
DropBox (does not work)
Amazon Cloud Drive (does not work)
As you see, in a browser (I have used Chrome to test) you will get the PDF documents to open, but not without some kind of context (except for the Xamarin one).
The code: I am developing in MonoTouch and I am using a component called mTouch PDF Reader. The code is simply:
var documentViewController = new DocumentViewController (1, "Some name here", "http://someurlhere.pdf");
ActivateController (documentViewController);
This opens a nice PDF reader inside my app, but, as I can't use my own created URLs this does not help me. This is a 3rd party library so I can't look at the code. By the way, when I use one of my URLs, the code crashes with a System.NullReferenceException with this stacktrace:
MonoTouch.Foundation.NSArray.FromNativeObjects (items={MonoTouch.UIKit.UIViewController[1]}, count=1) in /Developer/MonoTouch/Source/monotouch/src/shared/Foundation/NSArray.cs:109
MonoTouch.Foundation.NSArray.FromNativeObjects (items={MonoTouch.UIKit.UIViewController[1]}) in /Developer/MonoTouch/Source/monotouch/src/shared/Foundation/NSArray.cs:96
MonoTouch.Foundation.NSArray.FromNSObjects (items={MonoTouch.UIKit.UIViewController[1]}) in /Developer/MonoTouch/Source/monotouch/src/shared/Foundation/NSArray.cs:48
MonoTouch.UIKit.UIPageViewController.SetViewControllers (viewControllers={MonoTouch.UIKit.UIViewController[1]}, direction=MonoTouch.UIKit.UIPageViewControllerNavigationDirection.Forward, animated=false, completionHandler={MonoTouch.UIKit.UICompletionHandler}) in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIPageViewController.g.cs:144
mTouchPDFReader.Library.Views.Core.DocumentViewController.ViewDidLoad () in
MonoTouch.UIKit.UIApplication.UIApplicationMain () in
MonoTouch.UIKit.UIApplication.Main (args={string[0]}, principalClassName=(null), delegateClassName="AppDelegate") in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
Exam936.Application.Main (args={string[0]}) in /Users/EdGriMac/Dropbox/Quiz/Code/Exam926/Exam936/Main.cs:16
The frustration:
Is there a specific way to create URLs that work in this way? It does seem like DropBox does something different as it sort of iFrames the document or something. I don't know what Amazon Cloud Drive does. What has Xamarin done? Is it, as pointed out in the comments, because of http vs https?
I am completely lost. Am I missing something simple? Do you have any other way to create URLs to suggest? Googling this is really difficult as I continue to hit examples of how to share a URL in DropBox and so on...
By the way, I do not want to have the documents as part of the app as this means I will have to create a new version of the app just to change something in a document.
Update 1: I have added links above. I will try some other suggestions later and will leave more updates. Thanks in advance for any further suggestions!
Update 2: I have used Fiddler to look at the response on each of the URLs. The Xamarin URL has Content-Type: application/pdf while both DropBox and Amazon Cloud Drive has Content-Type: text/html; charset=UTF-8. This explains a lot. I will try andersr's suggestion later today as I do have a web server to put files on.
Update 3 When I put the PDF file on my Amazon EC2 server, created a virtual directory under my web site in IIS, the URL to my website + virtual directory + filename worked! Turns out the Content-Type had to be application/pdf for the mTouch PDF Reader to open it through a URL.
Thanks everyone for your help!
It seems to me that the first two URLS, link directly to the PDF files, but the latter one, ie. the one on Amazon Cloud Drive links to a page which again links to the PDF. I suggest the following potential solutions:
Find a reliable way to extract the direct url to the document on cloud drive. The link to the document is not the one you provided, but this: link . Perhaps Amazon has documentation on how you can avoid the html interface in order to retrive your file. I am not familiar with cloud drive at all. Note that the url provided has some time limited token attached to it.
Host the document on infrastructure you have more control over. IE. setup your own web server and host the documents there. Alternatively use another cloud storage provider which gives you the ability to link to files directly.
How do I reference a file outside my web site's root directory?
For example my website is located at C:\dev\TestSite
I am using ASP.NET with XSP. The webapp will be deployed on Apache using mod_mono.
I have images in C:\images and I would like to do this:
<img src="C:\images\logo.gif"/>
Your img tag's src value is going to be sent to the client. You need to specify those paths relative to your document root. Your best bet is to set up a virtual folder (in IIS, alias is the apache equivalent) to point to the c:\images path and then change the mentioned tag src path as follows
<img src="/images/logo.gif" />
To do this in apache, you need an alias in your httpd.conf. The line looks like this
Alias /images c:/images
Here's the docs http://httpd.apache.org/docs/2.0/mod/mod_alias.html#alias
While it might be possible to do this through some hacky method, it's not a good idea. Allowing the IIS account to access files/folders on the greater file system would be a big potential security hole.
The best way to accomplish this is to use IIS Virtual Directories. Put your content in folders dedicated to supporting the site, DO NOT make your entire C: drive a virtual directory.
I'm going to assume that C:\images\logo.gif is the path on the server, and not the path on the client.
The src attribute is interpreted by the html client (i.e. Internet Explorer). The client can't see anything outside of your web directory. In fact, the client can only see things inside your web directory if you've provided permission for them to do so. Thus, this isn't an ASP.NET issue, but an issue of how web clients have access to web servers... which is designed this way for security.
In order for your application to use these images, you've got a couple of options that immediately spring to mind - neither of which is ideal:
The ASP.NET code (in the codebehind) is going to need to go and grab the file, and serve it out in the html stream that is being served to the client, which is more a complex task than I suspect you are willing to embark on.
The ASP.NET code (using System.IO) is going to need to go and grab the file from it's home location in C:\images\logo.gif and copy it to a location that is accessible to the client - you could create a temporary directory, copy your image to it, serve it out, delete it, delete the directory.
Both of these are certainly hacks that should be avoided if possible, but if you're adamant that this is what you want to do, this will allow you to do it via your ASP.NET app.
The most ideal solution is to add C:\Images as a virtual directory to your document root, i.e. /ImageCentral - this way you can have images that are central to multiple websites stored in this directory, it can then be referenced by clients for any of the websites just by adding virtual directories to each of them pointing at the central images folder. As DaveSwersky points out, don't make any directories containing sensitive information virtual directories, the minute you add a virtual directory to an externally visible website, you're giving people free reign to any of the information in it.
Good luck
You can't do this from within the HTML code of your page. The HTML page can only reference web accessible content (in regards to images, CSS, javascript, etc). You could create a virtual directory that points to your images folder so that it becomes web accessible.
EDIT:
The apache way inside of your conf file.
Alias /images "C:/Images"
And a little walkthrough from some dude.