Static files and authentication in ASP.net - c#

Say I have a virtual folder /topFolder/ in IIS7, and in that folder there can be any file that can be displayed in a browser (xml, html, swf, doc etc - typically "unmanaged" resources from the IIS perspective).
Before giving the request permission to open any file below the folder, I need to check some session variables in order to see if the user has a "license" for the subfolder and file in question.
I've tried implementing a module with IHttpModule and IReadOnlySessionState interfaces, but the Session is always null on the AcquireRequestState event when the file is "static" and not IIS managed (like aspx, ashx etc).
If I use a custom HttpHandler, I get the session, but then I also need to implement how the content is sent to response. Edit: Since the user isn't downloading the file, I just want IIS to serve the file like it does with its StaticFileModule. The Handler/Module should really be a StaticFileModuleWithAuthorizationHook...
So I really want to do the following:
1. For request /topFolder/* : check session and licenses etc
a) If ok, continue serving file
b) If not ok, interrupt request, or just send FORBIDDEN in response.
Hope someone can help.

You should be able to handle this via the httphandler, the simple way is to use the built in methods to send the file down to the user if they have access.
This article (at the bottom) shows an example of how to do this.

Related

Restrict unauthorized access to file download using handler

I am working on a website where the images and other files are handled by a handler named resources.ashx. These files are not stored in any folder but are fetched from database.
The problem is the access to some of the files is restricted, whereas some images and files are open to all.
Lets say the path to one of the restricted image is :
../website/resources.ashx/restrictedimage.jpg
If an unauthenticated user types in this url, he will have access to the image straight away.
I want to restrict that.
P.S. -> I can't change the handler as I am referencing it from some other project.
May be an HttpModule can help you out. Handle the AuthenticateRequest event, parse/compare requested url and users/roles.
You can use authorization rules in your web.config to control access to the files (ie urls) or your choosing based on user/group membership.
See:
using multiple authorization elements in web.config

PDF binary data output in .NET

I have a question about outputting PDF files. Currently I'm storing the PDF in the database in binary form. I'm outputting the PDF file via a URL such as:
http://myhost.com/FileManager.aspx?FileId=8465b2f9-b64e-4a9a-a449-94b5adb3b278
so from what I could deduce, to the browser this is an .aspx page that is loading and not a PDF. Firefox and IE interpret this correctly and launch Adobe Acrobat, however since Chrome (12.0.742.112) has its own implementation of a PDF reader, it will open the file correctly, but then when someone goes to save the file in chrome, it wants to save it as a .aspx. If I simply rename the .aspx to .pdf, the file downloads correctly. However, I"m trying to avoid telling my customer that s/he may have to take that extra step.
When I chose to look at the headers that loaded in Chrome via Web Inspector, I see this:
FileManager.aspx:-1 Resource interpreted as Document but transferred
with MIME type application/pdf
I can completely understand why Chrome would say this.
Furthermore, I get a save as box upon page load when I add:
Response.AddHeader("content-disposition", "attachment;filename=blah.pdf");
However, I was hoping to just keep the file in a browser. So aside from using some URL Rewrite, is there a way I can manipulate the HTTP Headers to simply open the page as a PDF and save correctly in Chrome?
Lastly, I tried using a WebService, but I can't seem to write the binary data to the page.
this.Context.Response.BinaryWrite(bytes);
Any help is appreciated!
In the web application's top-level web.config, add the following <add> element to the <httpHandlers> section:
<httpHandlers>
<add verb="*" path="FileManager.pdf" type="ProjectName.FileManager" />
...where ProjectName.FileManager is the full name (namespace and classname) of the FileManager class in FileManager.aspx.cs.
This tells ASP.NET to handle the path /FileManager.pdf using the handler defined by ProjectName.FileManager. (System.Web.UI.Page implements the IHttpHandler interface, so every webform is a handler.)
Now you can serve the PDFs via a URL with a .pdf extension like so:
http://myhost.com/FileManager.pdf?FileId=8465b2f9-b64e-4a9a-a449-94b5adb3b278
You do not need to rename the physical FileManager.aspx file. When the user enters /FileManager.pdf?FileId=foo in the browser, ASP.NET will handle the request with the ProjectName.FileManager class defined in FileManager.aspx.
Note:
The above should work on Cassini (the Visual Studio "mini" webserver) with no further changes. However IIS by default only sends *.aspx, *.asmx, *.ashx requests to ASP.NET. Therefore, for the above to work on IIS, you need to tell it to send requests for /FileManager.pdf to ASP.NET. That is, you need to configure a "mapping".
With IIS 6 you need to configure the mapping using IIS manager.
With IIS 7 you can configure a mapping from your web.config--this makes deployment easier, but it depends on how your hosting is set up.
Something that worked for me was to add the intended filename between the application page name (in your case, FileManager.aspx) and the query mark (the ? mark).
So, in the end, you'd have something like this:
http://myhost.com/FileManager.aspx/myfile.pdf?FileId=8465b2f9-b64e-4a9a-a449-94b5adb3b278
Surprisingly, the correct application will run (Filemanager.aspx), the variables will be passed unharmed (FileId), the result will be treated as inline (if you didn't change it to attachment, that is) but the browser will think that the filename to use, in case the user wants to save the page, is myfile.pdf.

regarding multilanguage URL rewriting

I wanna implement url rewriting so that, for example, all german pages have a url with /de/ after the domain name (and english pages with an /en/) but I don't actually have to create and manage all those subdirectories. I want this "de"/en to persist through out the website
Just like mentioned in the article below:-
http://www.deevelop.com/en/web-design-company/blog/12/Multilingual-website.html
Please check the content under "SUBDIRECTORIES" heading in this article.
This article doesn't explain stuff in detail. Can I please have link to more such examples that are elaborative enough?
Or if someone has implemented such a thing may help. Thanks
URL rewriting is the process of intercepting an incoming Web request and redirecting the request to a different resource. When performing URL rewriting, typically the URL being requested is checked and, based on its value, the request is redirected to a different URL. For example, in the case where a website restructuring caused all of the Web pages in the /people/ directory to be moved to a /info/employees/ directory, you would want to use URL rewriting to check if a Web request was intended for a file in the /people/ directory. If the request was for a file in the /people/ directory, you'd want to automatically redirect the request to the same file, but in the /info/employees/ directory instead.
You first need to download SP1(free) and install it, then follow these links:
http://msdn.microsoft.com/en-us/magazine/2009.01.extremeaspnet.aspx
http://chriscavanagh.wordpress.com/2008/03/11/aspnet-routing-goodbye-url-rewriting/

POST data to a Flex/Flash (mxml) application

I have Flex application requiring to filter users depending on there database groups. Depending on which group they are, the're is a config.xml file that is use to populate the swf.
Here is how I figure how to do this :
1. The client comes to a .aspx page with a form requiring a username and a password.
2. On the server side I confirm the user credential
3. Once the username/password is valid I redirect to the mxml file with the config.xml file in the html headers (post).
My problem comes when I need to get the post data from the http request. Let's say I have this code :
<mx:Application initialize="init()">
<mx:Script>
<![CDATA[
private function init():void
{
// get the post data here
}
/* More code here */
]]>
</mx:Script>
</mx:Application>
How do I get the post data on the init() function.
Thank you.
For those that would be interested, I've found some ressources on the Adobe Flex 3 Ressource center.
Basically there is no current way to pass data with the POST method. You can either add the parameters at the end of you swf url (GET method) as shown here : http://livedocs.adobe.com/flex/3/html/help.html?content=deep_linking_5.html#245869
The other way is to embed them in the page with the flashVars method shown here : http://livedocs.adobe.com/flex/3/html/help.html?content=passingarguments_3.html#229997
If you still wonder, how I'll manage to do this if you run to in the same situation. Here is my idea (feel free to share if you have different vision) :
1.User logs in login.aspx
2.Depending on the credentials of the users the server side code modify the index.html file to embed the correct xml file in the flash object.
3.With the FlashVars method, I get back the xml file path and job done!
If you ever run in a similar situation and need help contact me.
I don't think it's possible to get the POST data, but others might have a way. An alternative solution would be:
User logs in: login.aspx
User directed to Flash content: content.html embedding content.swf
Flash requests config.xml from server: content.swf makes HTTP request for config.xml.aspx
Server provides user's configuration in config.xml.aspx
In your init() function, you'd make the URLLoader request to get the configuration, and you'd do the configuration in the Event.COMPLETE handler.
Another possibility is to use HTTP cookies--not handled natively by Flash, but you can get to them via Javascript--see this CookieUtil class.

Expose url to webservice

In our project we want to query a document management system for a specific document or movie. The dms returns a URL with the document location (for example: http://mydomain.myserver1.share/mypdf.pdf or http://mydomain.myserver2.share/mymovie.avi).
We want to expose the document to internet users and intranet users. The requested file can be large (large video files).
Our architecture is like:
request goes like: webapp1 -> webapp2 -> webapp3 -> dms
response goes like: dms -> webapp3 -> webapp2 -> webapp1
webapp1 could be on the internet.
I have have been thinking how we can obfuscate the real url from the dms, due to security issues. I have seen implementations from other webapps where the pdf URL was obfusicated by creating a temp file for the requested document that is specific for the session and user. So other users cannot easily guess the documentname of other users.
My question: is there a pattern that deals with exposing company/user vulernable data to the public ?
Our development is in C# 3.5.
The easiest way to handle it is to create a ashx file (or some other way of creating a URL) and have it serve the pdf. Since WCF supports REST you could always do it through that too. Just load the pdf into memory and push the byte contents into the response stream.
Alternatively, you might want to look into these:
http://www.microsoft.com/forefront/edgesecurity/isaserver/en/us/
http://www.isapirewrite.com/

Categories