Servicing HTTP PUT from .ashx handler in ASP.NET without tweaking file permissions - asp.net

I've got an .ASHX handler I want to use to process an HTTP PUT to allow me to upload files to the web server--the .ASHX file actually uploaded data and sticks the file elsewhere, so it never actually touches the disk here.
I've set the web.config to allow it to handle HTTP PUT, but IIS won't pass the request to my code unless I set the ACLs on the .ASHX files themselves to be writable--Which is kinda silly, since we're not actually going to write to those files.
If I set the ACLs, it works fine, but I'd like to be able to process the file without having to set the ACLs at all (I'm sure there's an appropriate way to make IIS just pass the HTTP PUT to the .ASHX file without checking the permissions on the file itself.
This is on Win2008 R2 (actually, it's on Azure's 2008 R2, but should be the same), using .NET 4.0
401 - Unauthorized: Access is denied due to invalid credentials.
You do not have permission to view this directory or page using the credentials that you supplied.

There are several roadblocks to getting PUT (and DELETE) working with ASP.NET. Since you mention Win2008 R2 (IIS 7.5) I would check to see if the errors you are seeing mention the WebDAV module or handler.
WebDAV is enabled by default as of IIS 7.5. It will interfere with HTTP PUT and DELETE verbs on ASP.NET handlers and modules. If you're implementing a RESTful service you likely don't even utilize this functionality. Disable it via your web.config.
<system.webServer>
<modules>
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
</handlers>
</system.webServer>
Some other solutions are mentioned in this forum post entitled HTTP Error 405 With ASP.Net MVC and HTTP PUT on IIS 7.5.

Related

Session Resets when uploading a file using a flash plugin

My session is getting reset after I upload file using a flash plugin. I put some logging into the Session_Start function and I see its called every time I upload a file using the flash plugin. I'm not sure what would be causing this. This is working locally for me in dev environment with the same server and settings.
I'm using
IIS 7 with Windows Server 2008 R2.
My app:
ASP.NET MVC .NET 4.0 (legacy app)
I upload other files on the site without the flash plugin and those work. This functionality worked before. But for some reason now it stopped working.
Any ideas on what could be causing this to occur?
First Microsoft End of support for Windows Server 2008 and Windows Server 2008 R2.
The default server configuration does not allow you to upload files with Flash Uploader.
You could try below settings:
1)Disabling Request Validation:
ASP.NET automatically validates a request or rejects it if there are dangerous fields. However, HTML5/Flash Uploader sends files data in text fields (instead of binary ones) due to Adobe Flash Player limitations. IIS may treat this behavior as potentially dangerous and, thus, you can get the following error during uploading:
A potentially dangerous Request. Form value was detected from the client
use below code to disable the request validation on the page which processes the upload request:
<%# Page Language="C#" ValidateRequest="false" %>
2)Assign permission:
The folder where you are going to save files should have modified permissions.
Assign the iis_iusrs and iusr or application pool identity full permission to the upload folder.
3)Configuring Maximum POST Request Length:
Usually, the limitation for maximum POST request length is specified to reduce the risk of DoS attacks. If the request size exceeds a specific value, it is considered malicious and the upload would be broken.
If you are going to upload files larger than the default limitation, increase the latter.
Go to C:\Windows\System32\inetsrv\config\applicationHost.config and change
<section name="requestFiltering" overrideModeDefault="Deny" />
To
<section name="requestFiltering" overrideModeDefault="Allow" />
add below code in your application web.config file:
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength ="2147482624" /> <!-- in bytes -->
</requestFiltering>
</security>
</system.webServer>
<system.web>
<httpRuntime maxRequestLength="2097151"/> <!-- in kilobytes -->
</system.web>
4)Configuring Control to Support Medium Trust Level:
.NET Trust Level in IIS specifies the level of code access security for ASP.NET applications. By default, HTML5/Flash Uploader works under the full trust level. However, if you create a website with the medium trust level on your server, you should configure HTML5/Flash Uploader to support this level as well. To perform this, just set the MediumTrustCompatibility property to true as the snippet below shows:
<aur:ImageUploaderFlash ID="ImageUploaderFlash1" runat="server"
MediumTrustCompatibility="true">
</aur:ImageUploaderFlash>
Setting the MediumTrustCompatibility property to true requires an application's pool to be routed to a single worker process. To perform this run IIS Manager, choose the application pool under which your website works, click Advanced Settings in the Actions panel, and set Maximum Worker Processes to 1:

<modules runAllManagedModulesForAllRequests="true" /> Meaning

I wanted to know what is the meaning of
<modules runAllManagedModulesForAllRequests="true" />
I am using IIS 7.5 and I have a simple web application. Do I need to write this in my web.config file.
I have also written few http handler for jquery ajax call.
I am using form authentication and asp.net 4.0.
How can I determine which module I have to run and which is not to be?
Modules Preconditions:
The IIS core engine uses preconditions to determine when to enable a particular module. Performance reasons, for example, might determine that you only want to execute managed modules for requests that also go to a managed handler. The precondition in the following example (precondition="managedHandler") only enables the forms authentication module for requests that are also handled by a managed handler, such as requests to .aspx or .asmx files:
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" preCondition="managedHandler" />
If you remove the attribute precondition="managedHandler", Forms Authentication also applies to content that is not served by managed handlers, such as .html, .jpg, .doc, but also for classic ASP (.asp) or PHP (.php) extensions. See "How to Take Advantage of IIS Integrated Pipeline" for an example of enabling ASP.NET modules to run for all content.
You can also use a shortcut to enable all managed (ASP.NET) modules to run for all requests in your application, regardless of the "managedHandler" precondition.
To enable all managed modules to run for all requests without configuring each module entry to remove the "managedHandler" precondition, use the runAllManagedModulesForAllRequests property in the <modules> section:
<modules runAllManagedModulesForAllRequests="true" />
When you use this property, the "managedHandler" precondition has no effect and all managed modules run for all requests.
Copied from IIS Modules Overview: Preconditions

404 handling - Difference between local ASP.Net (C# 4) and remote server (live)

I'm facing a problem:
I do want to do URL rewriting with ASP.Net
It works perfectly using my local settings, but once on the server it doesn't work as expected.
Local
Request to /unavailable-file.aspx gets well in the Application_Error (Global.asax.cs) and then is being redirected to /404.aspx
Request to /unavailable-random-folder or any other file gets well in the Application_Error (Global.asax.cs) and then is being redirected to /404.aspx
Remote
Any request to a .aspx file WILL be catched in the Application_Error
Every other request (.jpg, folder, etc...) will NOT be catched at all and thrown into the default 404 page error
My problem:
Yesterday I was installing my new website to the server and I saw that Application_BeginRequest was not even fired AT ALL on my server, when it was every time (for every file or folder requested) in my local computer (with visual studio).
I had to create an HttpModule and now I am successfully getting the events firing... but not for non .aspx requests.
Everything seems to be bound on the URL : when it ends with .aspx it's correctly managed and when it's not, it's just not managed at all.
What should I do to catch every Application_BeginRequest even for non aspx page?
I have that in my web.config to try to force the 404 errors into my page:
<customErrors mode="On"
defaultRedirect="404.aspx">
<error statusCode="404" redirect="404.aspx"/>
</customErrors>
But as I said, as long as it's not a request ending with .aspx it's not being redirected and I get the default ASP.Net 404 error.
(My host is "reliablesite" if it can help, and I have the settings of the 404 errors pointing to my 404.aspx page inside the manager (shared hosting), it does not change anything)
I wish everything would work as in local mode.
If you have any tip on how to resolve that problem let me know.
In the development web server every request is handled by the aspx engine, as that's all there is. In the live server different file types are handled by different engines.
To make the live server use the aspx engine for every request you have to change the configuration in IIS for the web site.
Related: ASP.net web.config doesn't catch all 404's
The solution of this problem is given here when you have a shared environment:
Active the ASP.Net Integrated Pipeline in your shared environment settings (a thing that is available since IIS 7)
Add this to the web.config:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="RedirectHttpModule" type="RedirectHttpModule" />
</modules>
</system.webServer>
Where RedirectHttpModule is a custom module handling Application_BeginRequest for example.
The "runAllManagedModulesForAllRequests" means that all managed modules will be invoked for all requests to web application.

How to deny access to a file with ASP.NET web config but not just locally?

I have a problem with ASP.NET web configuration file. I want to deny some users or roles to accessing a specific PDF file. I am using ASP.NET membership and role management system. So I added this lines of codes to a Web.config file:
<location path="myfile.pdf">
<system.web>
<authorization>
<allow roles="admin"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
and put it to the directory witch the file is included in it. Now when I run the project in local system I can not access the PDF file wile I login with "admin" role. But when I publish the project on the web server I can not brows the folder but I can view the PDF file when I browse complete path to the PDF file. So:
I can not access: http://www.example.com/folder
but I can view: http://www.example.com/folder/myfile.pdf
IIS is probably serving the PDF file before ASP.Net gets its hands on it. Assuming you're using .Net 4.0, add this to your Web.config file to force all requests to flow through to ASP.Net:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<system.webServer>
You need to make IIS forward PDF requests to ASP.NET for your stuff to take place.
Example Article:
http://www.primaryobjects.com/CMS/Article112.aspx
Quoting relevant part from article:
Hooking PDF Files Into the Web
Application with IIS
It was easy testing the custom HTTP
handler in Visual Studio's built-in
web server, Cassini, since all
document types are automatically
processed in the web application by
default. However, IIS needs a few
tweaks. IIS will ignore sending
requests for static documents, such as
PDF files, to the ASP .NET web
application and will instead simply
serve the request. We need to
intercept the request and allow our
web application to process it first.
To do this, we'll need to setup an IIS
mapping for PDF files (*.pdf), telling
IIS to send the request to our web
application.
In IIS 5/6
Open the Internet Information Services (IIS) Manager.
For your web application, on the Directory tab, click the Configuration
button.
On the Mappings tab of the Application Configuration window,
click the Add button to add a new
Application Extension Mapping.
In the Executable field, enter: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll
In the Extension field, enter: *.pdf
Select All Verbs and checkmark Script Engine and Check that file
exists.
In IIS 7
Open the Internet Information Services (IIS) Manager.
Open the Handler Mappings setting.
Add a Managed Handler.
For Request Path enter: *.pdf
For Type, select the custom HTTP handler for the application.
A shortcut to this in IIS 7, as
mentioned above in the article, is to
define the mapping in the web.config
within the system.webServer handlers
section, as follows:
<system.webServer>
...
<handlers>
<add name="PDF" path="*.pdf" verb="*" type="CustomFileHandlerDemo.Handlers.FileProtectionHandler" resourceType="Unspecified" />
...
</handlers>
</system.webServer>
The above code in the web
application's web.config will
automatically add the entry into the
IIS 7 Handler Mappings section.
The above steps may differ depending
on your version of IIS, but should be
similar for adding a document mapping
to the web application. Once
configured, requests for PDF documents
will be sent to the web application,
where you can process the request
before allowing access.
Remember, in Visual Studio's built-in
web server, module mappings are not
required, as all requests for files go
through the web application, making it
easy to test the custom http handler.
Because you don't use custom handler, you just need to set the handler to ASP.NET default handler. This is the same handler set to ".aspx" already in IIS.

httpModule for 404

I've created an httpModule to handle URL remappings, and it works great on my test system. A request for www.mydomain.com/Some_Fancy_URL gets rewritten to www.mydomain.com/some.aspx?fancy=23 and so on.
When I deploy to the actual web site, I'm getting the default IIS 404 page though.
After doing some research online, it would seem that I need to setup "Wildcard Mapping" in IIS 6 to get the request past IIS and in to my httpModule. The problem is that the site is hosted on a shared server, so it may not be possible to get the ISP to make that change.
My question is, can't I use an httpHandler to tell IIS how I want these requests handled? For example:
<httpHandlers>
<add path="*.aspx" verb="GET,POST" type="System.Web.UI.PageHandlerFactory" validate="false"/>
</httpHandlers>
It would seem like adding this to my Web.Config should tell IIS to stop validating the existence of .aspx files, and just pass the request along for me to process. It doesn't work though.
Any suggestions?
The problem with IIS 6 and ASP.NET is that they're aren't integrated. IIS needs to be told about ASP.NET via script mappings (.aspx, .asmx, wildcard and so on).
None of your web.config configuration settings will influence IIS because web.config is there to configure ASP.NET's behaviour, not IIS. IIS has no knowledge of web.config.
Unless you can hand off a request to the ASP.NET pipeline (via a script map) nothing will happen and all your web.config settings will be ignored.
With IIS 7 the story is quite different. In IIS7, ASP.NET and IIS are closely integrated and share the same pipeline thus permitting you to achieve the result you're looking for.
The alternative may be to find out if your hoster runs a URL rewriter such as ISAPI_Rewrite on their servers. That way you could rewrite urls without having to map a wildcard scriptmap to IIS6.
Through some trial and error, along with more web searches, I found a solution. It essentially parallels Kev's answer.
IIS won't treat a request as .NET unless it has a known file extension (.aspx, .ascx, etc.). When I send along something like www.mydomain.com/anything it looks for a file or folder named "anything", and when it doesn't find one, it just drops off to the default IIS 404 handler.
That's where I took over. I changed IIS 6 to forward 404 problems to /404.aspx. I then created that page with a generic "Your file wasn't found" message in the same style as my web site.
Here's the good part: Now that IIS is sending 404's to a .NET page, the custom httpModule I created is getting fired. The request is for 404.aspx, but IIS is nice enough to also append the original URL as well. You get something like:
www.mydomain.com/404.aspx?404;http://www.mydomain.com/anything
This allows me to parse the request in the httpModule, and rewrite as needed!

Resources