Can I use wildcards in the web.config location path attribute? - authentication

In IIS 7 I try to deny access to all files with the extension .xml for all users.
I tried the following setting in my web.config file:
<location path="*.xml">
<system.web>
<authorization>
<deny users="*"/>
</authorization>
</system.web>
</location>
But then getting any file results in an internal server error.
It works if I deny access to the individual files but this solution does not buy me much as I do not know all .xml files in advance.

Try this:
<configuration>
<system.web>
<httpHandlers>
<add path="*.xml" verb="*"
type="System.Web.HttpNotFoundHandler" />
</httpHandlers>
</system.web>
</configuration>
By the way you could alternatively store all of your xml files within the App_Data directory. Storing files of any type in this directory will not be served to the web.

Another way is to use a request filter:
<system.webServer>
<security>
<requestFiltering>
<fileExtensions>
<add fileExtension=".xml" allowed="false" />
</fileExtensions>
</requestFiltering>
</security>
</system.webServer>

I have stumbled across this when searching for a way to change the security applied to all actions within a controller in a legacy application (ASP.NET MVC). I thought I need some sort of wildcard, but simply providing the path including the controller segment is enough:
This allows anonymous access to all actions within FooController.

Related

How to use MaxRequestBodySize in ASP.NET Core on IIS with maxAllowedContentLength?

I have an ASP.NET Core web API running on IIS. In an operation, I set IHttpMaxRequestBodySizeFeature.MaxRequestBodySize to 262144000. I have used the IIS Configuration Editor to
modify ApplicationHost.config for my site by setting system.webServer/security/requestFiltering/requestLimits/maxAllowedContentLength to 4294967295
modify ApplicationHost.config for my site by setting system.webServer/serverRuntime/maxRequestEntityAllowed to 4294967295
modify Root Web.config for my site by setting system.web/httpRuntime/maxRequestLength to 2147483647
Those are the values I also see when I choose Web.config in the IIS Configuration Editor.
The site is behind another IIS site acting as a reverse proxy. I have made the same changes there.
I am able to upload files larger than the default ~30MB limit, but I consistently get the following warning whenever I set IHttpMaxRequestBodySizeFeature.MaxRequestBodySize to a large value:
Increasing the MaxRequestBodySize conflicts with the max value for IIS limit maxAllowedContentLength. HTTP requests that have a content-length greater than maxAllowedContentLength will still be rejected by IIS. You can disable the limit by either removing or setting the maxAllowedContentLength value to a higher limit.
I have even looked at the ASP.NET source code to verify that the warning only prints if you're trying to set the limit higher than the IIS settings ([1], [2]).
What am I doing wrong?
If it's relevant, I am publishing to IIS using Azure Pipelines. My repo does not contain a web.config, but for good measure I tried with the following web.config without luck:
<configuration>
<system.web>
<httpRuntime maxRequestLength="2147483647" />
</system.web>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="4294967295" />
</requestFiltering>
</security>
</system.webServer>
</configuration>
Turns out there are several bugs in ASP.NET Core when setting the limits to values above Int32.MaxValue. Furthermore, the limit must be set in two places. See this issue and linked issues. In summary:
Set the web.config value system.webServer.security.requestFiltering.maxAllowedContentLength to Int32.MaxValue
In the app startup, set IISServerOptions.MaxRequestBodySize to Int32.MaxValue
That removes the warning (and of course limits requests to ~2GB).
Try to set the below code in Startup.cs file:
services.Configure<FormOptions>(opt =>
{
opt.MultipartBodyLengthLimit = YOUR_MAX_TOTAL_UPLOAD_SIZE;
});
You could configure/modify maxAllowedContentLength property in your local web.config and deploy your app with web.config to your Azure Website.
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout">
<environmentVariables />
</aspNetCore>
</system.webServer>
</location>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="YOUR_BYTES" />
</requestFiltering>
</security>
</system.webServer>
</configuration>

Aspnet Core - web.config Authorization

I am trying to add "authorization" elements to web.config, like it used to work in classic asp.net:
global configuration - should limit access "globally":
<configuration>
<system.web>
<authentication mode="Windows" />
<authorization>
<allow roles="AD\some.user" />
<deny users="*" />
</authorization>
...
"location" based configuration:
<configuration>
<location path="RelativePath" >
<system.web>
<authorization>
<allow roles="AD\some.user" />
<deny users="*" />
</authorization>
</system.web>
</location>
both versions appear to be not working at all for aspnet.core hosted in IIS
What does work is this:
"global":
<configuration>
<system.webServer>
<security>
<authorization>
<remove users="*" roles="" verbs="" />
<add accessType="Allow" roles="AD\johannes.colmsee" />
</authorization>
</configuration>
"location" based:
<configuration>
<location path="RelativePath" >
<system.webServer>
<security>
<authorization>
<remove users="*" roles="" verbs="" />
<add accessType="Allow" roles="AD\denis.kopic" />
</authorization>
</security>
</system.webServer>
</location>
This works fine.
Now to my question:
does aspnet core not support the "first version" at all? Or is it something I do wrong?
ASP.NET Core does not support nor use web.config. The published web.config is there only for IIS hosting, since IIS requires this. If you happened to publish to a different web server, you could discard web.config entirely.
It should be apparent from looking at the contents of the published web.config, that it is extremely bare. Pretty much the only thing that exists is the AspNetCoreHosting module config, which of course is necessary for hosting ASP.NET Core inside IIS.
Now, as for why the second version actually did work, that's because it was placed inside system.webServer, which is directly for configuration of IIS, so IIS is doing the authorization at a very high-level before anything is handed off to your ASP.NET Core app. That may work for your needs, but it's an extremely rough-shod approach, as you'll have to likely end up defining many such sections for different paths, users, and authorization levels, and then keep that in sync with anything you end up changing in the ASP.NET Core app. Because IIS is looking at this as just static paths, if you move or rename anything, you can end up accidentally opening a hole in your security, since IIS will not yet have been configured to authorize that new location.
Long and short, you should remove all this and handle authorization via your ASP.NET Core app. Windows Auth is still supported.

Disable Anonymous Authentication in IIS cause Error 404.15

As title, I want to disable Anonymous Authentication for my ASP.NET Boilerplate web site (MVC) in IIS Server and use Form Authentication instead. Is it possible to do this because if I disable Anonymous Authentication, my website cause an error "HTTP Error 404.15 - Not Found"
Update 1: Here is my web.config
<system.web>
<globalization culture="auto" uiCulture="auto" />
<compilation debug="true" targetFramework="4.6.1">
<assemblies>
<add assembly="System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</assemblies>
</compilation>
<httpRuntime targetFramework="4.5.1" />
<customErrors mode="Off">
<error statusCode="404" redirect="~/Error/E404" />
</customErrors>
<httpHandlers>
<add path="Reserved.ReportViewerWebControl.axd" verb="*" type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" validate="false" />
</httpHandlers>
<authentication mode="Forms" />
</system.web>
I still remember the first time I had to implement Forms Authentication in ASP. All I can say is there is a reason I only do linux based web-development now!
It is a real pain, but this should work if you don't intend on using a database to manage the users.
If you do intend to use a database then prepare yourself for a long road. U need to have the correct MSSQL database for the correct Visual studio tool and they also removed the management interface completely so you either have to design your own or use a tool that is available on the internet somewhere. I still remember I got so frustrated by the whole idea of it, that I literally wrote my own management tool I could deploy on developed sites. If it wasn't on a broken harddrive I would give it to you.
<authentication mode="Forms">
<forms loginUrl="login.aspx" defaultUrl="welcome.aspx">
<credentials passwordFormat="Clear">
<user name="abhishek" password="abhi#123"/>
<user name="Kantesh" password="sinha#123" />
</credentials>
</forms>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
If you plan on using a database to store your users google some tutorials.
The reason why you are getting a 404 is because you are not specifying loginUrl or it is incorrect and pointing to a non-existant page.
Hope this helps
When you disable anonymous access to all pages you cannot let users to see login page as well. what you need to to do is allowing some specific pages like login or register to be accessible.
This might not completely fits for you but you get the idea.
If it doesn't work, try removing the backslash "/" for the "/account/login" and set it like "account/login"
<configuration>
<system.web>
<authentication mode="Forms" />
<authorization>
<deny users="?" /> //this will restrict anonymous user access
</authorization>
</system.web>
<location path="/account/login"> //path here is path to login page
<system.web><authorization><allow users="*" /> // this will allow access to everyone to login page
</authorization></system.web></location>
</configuration>

Windows Authentication allow users not working

I am trying to use windows authentication for my application, for the testing I have tried allowing to only myself and deny all rest
<authentication mode="Windows" />
<authorization>
<allow users="DomainName\nogariyap" />
<deny users="*"/>
</authorization>
But it gives me "Access Denied" error even I am logged in to my machine with the same user "DomainName\nogariyap"
When I change it to this
<allow users="*" />
it works
I don't know why it is not working for particular windows user?
Edit
It strangly worked when I added this in system.webServer
<security>
<authentication>
<windowsAuthentication enabled="true" />
<anonymousAuthentication enabled="false" />
</authentication>
<authorization>
<remove users="*" roles="" verbs="" />
<add users="DomainName\nogariyap" accessType="Allow"/>
<add users="?" accessType="Deny"/>
</authorization>
</security>
But I don't know why it is not working with the settings in system.web and what are the difference in these two settings?
<system.web> is the projects configuration and <system.webserver> is the server configuration. Both should be compatible but the recommendation seems to be to use the server configuration over the other. It was introduce on IIS7. Some of the differences between both are:
In system.webserver the order:
Deny rules get evaluated first starting at the parent
Allow rules starting at the parent.
Order of appearance in rule collection
In system.web the order:
Lower level first going up to the parent
Order of appearance in rule collection
In webserver you can apply rules to any element meaning: images, documents without further configuration(adding mapping between every extension you want to a handler)
in the first attempt you had deny users="*" meaning deny everyone. in the second attempt, you had deny users="?" meaning unknown users (not signed in).

Webservice does not seem to be doing any authentication despite config in IIS7.5

The Problem
I have a WCF webservice that I am hosting as a webservice in IIS7.5. I want this service to only be accessible by two groups. The webservice is running successfully, although there does not seem to be any authentication being done.
I was under the impression ( having read gobs of MSDN pages attesting to this) that all one really had to do was enable Windows Authentication on the Application site, disable Anonymous Authentication, set the mode to windows in the web.config and add Allow/Deny rules to the authorization section as diaplayed below:
<system.web>
<authentication mode="Windows" />
<compilation debug="false" strict="false" explicit="true" targetFramework="4.0" />
<pages /> <!-- Omitted -->
<authorization>
<allow roles="Managers" />
<allow roles="Operations" />
<deny users="*" />
<deny users="?" />
</authorization>
</system.web>
With the above steps and web.config changes done, and after going to the Authorization page in IIS and reloading the Auth rules, calling the service through the WCFTestclient shows it working flawlessly. Except I am not part of either of those two groups...
The Questions
It looks like it is just letting anyone in. My questions are these:
Is there a way to see passed and failed authentication checks on the webservice? (If so, I can see if any kind of authentication is going on).
Does the above look correct? It seems a bit simple, but given the Microsoft Method, it is not far fetched that something so standard would be fairly simple to set up.
Bottom-line
I have a service with the above web.config file, and an IIS7.5 instance with Windows Authentication installed and enabled. Anonymous Authentication is disabled. Auth rules are defined for two groups to have access, and all others to be denied and yet despite the fact that I am in those groups, I can access the service.
EDIT:
So I appear to have authentication working. If I only have the Allow All Users rule in place, I have access to the webservice. If I enact a Deny All Users rule, I no longer have access. However, if I add my account ("domain\MyAccount" as an allow (regardless of position in the web.config) I still don't have access.
What I have changed to get here,
Added the following to the service definition:
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Required)> _
Added the following to the web.config:
<system.web>
<authentication mode="Windows"/>
<authorization>
<deny users="*"/>
<allow users="sierra\cblissittekeps"/>
</authorization>
</system.web>
and
<system.servicemodel>
<bindings>
<basicHttpBinding>
<binding name="ADServiceBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<system.servicemodel>
Alright! So apparently the steps I took in the original post are not in fact enough. You have to add that aspnetcompatabilityrequirements attribute to the service class (which implements your service iterface), you have to add to the serviceHostingEnvironment tag an aspNetCompatibility attribute:
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"
aspNetCompatibilityEnabled="true" />
And, something that no-one seems to mention, the order of your Allow/Deny rules makes a difference. Adding an allow AFTER a Deny All Users means that all users are still denied. Putting it before means that all users are denied except the ones in the allow.